如何从基础 class 派生 class 类型

How the get derived class type from base class

我正在尝试重构我在很多课程中使用的方法。举个例子说明更简单。

我有这个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);
        }
    }

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

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

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

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?)

当您调用 GetDescription 方法时,它将是基础 class 对象本身或某些派生的 class 对象。但是在基地你不知道它是哪个派生class。您将需要使用 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);
}

最好保持为实例方法,如果你真的需要它作为static那么你需要将对象作为参数输入:

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. 使用 this.GetType()
  2. 获取类型的非静态方法
  3. 静态方法,提供 class 的实例作为函数 参数.
  4. 静态泛型方法,不提供实例。

为了简单起见,我会选择非静态的,但这取决于你想给它的用法。根据您对问题的评论,您可以利用泛型。

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