如何从基类获取派生类的类型

时间:2019-09-05 06:50:42

标签: c# hierarchy

我正在尝试重构一种在很多情况下使用的方法。通过示例进行解释比较简单。

我上了这个课:

    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);
        }
    }

在项目中,我还有一个用于本地化的ResourceFile。 GetDescription方法使用给定值的正确属性名称返回本地化文本。您可以看到一个使用示例:

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

问题是,我必须在所有const类中复制粘贴该方法。我正在尝试在基类中实现此方法,例如:

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);
    }
}

但是我不知道如何用var property = typeof(TipoPuntoClaveConst)代替var property = typeof(¿this?)

2 个答案:

答案 0 :(得分:2)

调用GetDescription方法时,它将是基类对象本身或某些派生类对象。但是在基础上,您不知道它是哪个派生类。您将需要使用GetType方法来获取运行时的实际类型,如注释中提到的 @ bradbury9

public string GetDescripcion(int IdxTipot)
{
    var property = this.GetType()
            .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);
}

最好将其保留为实例方法,如果确实需要将其作为静态对象,则需要将对象作为参数输入:

public static string GetDescripcion(int IdxTipo,TipoPuntoClaveConst objec)
{
    var property = object.GetType()
            .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);
}

答案 1 :(得分:1)

只要您的问题与类型和继承有关,我在向您解释您所拥有的替代方法,但避免了反射部分。

  1. 使用this.GetType()的非静态方法获取类型
  2. 静态方法,将类的实例作为函数提供 参数。
  3. 静态通用方法,不提供实例。

出于简单性考虑,我会选择非静态方法,但这取决于您要使用的用法。从对问题的评论中,您可以利用泛型。

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
    {
    }
}

输出为下一个

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