【问题标题】:How to get values from derived classes by reflection in C# dynamically?如何通过 C# 中的反射动态地从派生类中获取值?
【发布时间】:2021-10-03 23:45:06
【问题描述】:

我的代码有一个基类和两个派生类:

public abstract class BaseClass
    {
        public BaseClass(string message)
        {
            //TODO
        }
        public abstract int ErrorCode { get;  }
        public abstract string ErrorName { get; }
    }

    public class Concrete1 : BaseClass
    {
        public Concrete1(int p1, string message) : base(message)
        {
            //TODO
        }

        public override int ErrorCode { get; } = 1022;
        public override string ErrorName { get; } = "NotFound";
    }
    public class Concrete2 : BaseClass
    {
        public Concrete2(int p1, int p2, string message) : base(message)
        {
            //TODO
        }

        public override int ErrorCode { get; } = 1023;
        public override string ErrorName { get; } = "NotSettle";
    }

现在我想通过使用反射来获取所有派生类并获取它们的参数值,包括 ErrorCodeErroName。这是我获取所有正在工作的派生类的代码:

 public static List<Type> GetAllDerivedTypes(Type type)
    {
        var assemblies = AppDomain.CurrentDomain.GetAssemblies();
        _listTypes = new List<Type>();
        foreach (var item in assemblies)
        {
            _listTypes.AddRange(item
                .GetTypes()
                .Where(t => t != type && type.IsAssignableFrom(t))
                .ToList());
        }

        return _listTypes;
    }

但是为了获取值,我的代码不起作用:

   var listOfDerived = GetAllDerivedTypes(typeof(ExceptionBase));
        var src = listOfDerived.First();//for instance

        Type[] emptyArgumentTypes = Type.EmptyTypes;
        var p = ((ObjectType)Activator.CreateInstance(src, true)).GetType().GetConstructor(emptyArgumentTypes);

我该如何解决这个问题?

【问题讨论】:

  • 对不起,我不能完全按照您在第二步中尝试做的事情。 “在字典中插入两个参数值,包括ErrorCode和ErroName”是什么意思?我不明白你展示的代码是为了完成什么(为了第二个目标)
  • @Flydog57 我想从派生类中获取参数值(ErrorCode, ErrorName) 并将它们全部放入字典中,例如字典
  • 您的设置使您想要完成的工作变得非常困难;具体来说,您需要一个 类的实例 来反射性地获取字段或属性值;然而,您有不同的构造函数,并且没有默认构造函数 - 所以除非您维护派生类到工厂方法(或某些实例化方法)的映射,否则获取派生类的ErrorCodeErrorName 属性的值是不可能的。添加一个统一的构造函数(例如,一个接受string message 的构造函数),以便所有派生类型都可以以多态方式实例化。
  • @CoolBots 你的解释很棒。

标签: c# reflection


【解决方案1】:

Activator.CreateInstance(src, true) 已经使用默认构造函数创建了一个实例。 如果每个派生类都有一个默认构造函数。

所以

var p = ((ObjectType)Activator.CreateInstance(src, true));

应该够了。

但是你没有默认构造函数。

另一方面,您可以使用以下方法调用其他构造函数:

src.GetType().GetConstructor(...)

但您应该为所有派生类使用相同的构造函数原型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 2019-03-09
    • 2010-11-22
    • 1970-01-01
    • 2017-08-21
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多