Search code examples
c#hierarchy

How the get derived class type from base class


I'm trying to refactor a method which I use in a lot of clases. It's simpler to explain it by an example.

I have this class:

    public class TipoPuntoClaveConst
    {
        public const int Insercion = 1;
        public const int DetectorDePaso = 2;
        public const int Sincronizador = 3;
        public const int Extraccion = 4;

        public static string GetDescripcion(int IdxTipo)
        {
            var property = typeof(TipoPuntoClaveConst)
                .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
                .Where(fi => fi.IsLiteral && !fi.IsInitOnly && (int)fi.GetRawConstantValue() == IdxTipo)
                .FirstOrDefault();

            if (property == null) return string.Empty;
            var name = property.Name;
            return ResourceHelper.GetTraduccion(ResourceHelper.FICHERO.General, name);
        }
    }

In the project, I also have a ResourceFile for localization. The GetDescription method, returns the localized text using the correct property name given a value. You can see an example of use:

<html>
    <body>
        <select id="cbTipo">
            <option value="@TipoPuntoClaveConst.Insercion">@TipoPuntoClaveConst.GetDescripcion(TipoPuntoClaveConst.Insercion)</option>
            ...
        </select>
    </body>
</html>

The problem is, that I have to copy-paste that method in all of my const classes. I'm trying to implement this method in a base class, something like:

public class TipoPuntoClaveConst : ConstMaster {...}

public class ConstMaster {
    public static string GetDescripcion(int IdxTipo)
    {
        var property = typeof(TipoPuntoClaveConst)
            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
            .Where(fi => fi.IsLiteral && !fi.IsInitOnly && (int)fi.GetRawConstantValue() == IdxTipo)
            .FirstOrDefault();

        if (property == null) return string.Empty;
        var name = property.Name;
        return ResourceHelper.GetTraduccion(ResourceHelper.FICHERO.General, name);
    }
}

But I cannot figure out, how to replace var property = typeof(TipoPuntoClaveConst), for something more general, like var property = typeof(¿this?)


Solution

  • As long as your problem is with types and inheritance, I am explaining you the alternatives you do have but avoiding the reflection part.

    1. Non static method getting the type using this.GetType()
    2. Static method, providing an instance of the class as an function parameter.
    3. Static generic method, not providing and instance.

    I would go the non-static because of simplicity, but it depends on the usage you want to give it. From your comments on your question, you could take advantage of generics.

    namespace InheritanceTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine($"Base: {new BaseClass().CheckType()}");
                Console.WriteLine($"Child: {new ChildClass().CheckType()}");
                Console.WriteLine($"Static in base with child argument: {BaseClass.CheckType(new ChildClass())}");
                Console.WriteLine($"Static generic in base:{BaseClass.CheckType<ChildClass>()}");
                Console.ReadLine();
            }
        }
    
        public class BaseClass
        {
            public string CheckType()
            {
                return this.GetType().ToString();
            }
    
            public static string CheckType(BaseClass instance)
            {
                return instance.GetType().ToString();
            }
    
            public static string CheckType<T>() where T: BaseClass
            {
                return typeof(T).ToString();
            }
        }
    
        public class ChildClass : BaseClass
        {
        }
    }
    

    The output is the following one

    Base: InheritanceTest.BaseClass
    Child: InheritanceTest.ChildClass
    Static in base with child argument: InheritanceTest.ChildClass
    Static generic in base: InheritanceTest.ChildClass