使用反射在静态类中调用静态属性的非静态成员

时间:2018-02-04 23:48:30

标签: c# reflection system.reflection

我有一个静态类,它查找抽象类型的实现并将其存储为静态属性 类似于以下内容:

public static class MyStaticClass
{
    private static MyAbstractType _MyAbstractImplementation;

    public static MyAbstractType MyAbstractImplementation
    {
        get => _MyAbstractImplementation ?? ( _MyAbstractImplementation = FindImplementation());
        private set => _MyAbstractImplementation = value;
    }
}

我试图通过反射调用MyAbstractImplementation的方法(它不包含静态属性或方法):

var myAssembly = Assembly.Load("MyStaticClassAssembly")

var myType = myAssembly.GetTypes().First(t => t.Name == "MyAbstractType");

var myImplementation = myType.GetProperties()
    .First(p=>p.ReflectedType?.Name == "MyAbstractImplementation")
    .GetValue(null);

var obj = myType.GetMethod("SomeMethod")?.Invoke(
                null,
                new object[] 
                {
                    // Some args
                });

以上代码在获取MyAbstractImplementation

的值时会导致以下异常
System.Reflection.TargetException: Non-static method requires a target.

显然,这是因为我将null传递给GetValue(),所以我尝试传递myAssembly而不是null,我得到以下异常:

System.Reflection.TargetException: Object does not match target type.

出于绝望,我尝试传递myTypemyImplementation,但我仍然得到同样的例外。

我打算传递给GetValue()是什么意思?

1 个答案:

答案 0 :(得分:1)

从您收到的错误MyAbstractImplementation不是静态属性,因此需要运行实例。您基本上是在尝试编写以下代码:

new MyAbstractType().MyAbstractImplementation.SomeMethod();

属性和方法访问都需要针对目标运行('。'的左侧)。所以你需要一个myType的实例。此方法还需要实例,这是获取属性(myImplementation)的结果。

var myAssembly = Assembly.Load("MyStaticClassAssembly");

var myType = myAssembly.GetTypes().First(t => t.Name == "MyAbstractType");
var myTypeInstance = Activator.CreateInstance(myType);  // Asuming has a default constructor 

var myImplementation = myType.GetProperties()
    .First(p => p.ReflectedType?.Name == "MyAbstractImplementation")
    .GetValue(myTypeInstance);

var obj = myType.GetMethod("SomeMethod")?.Invoke(
                myImplementation,
                new object[]
                {
                    // Some args
                });

如果代码myImplementation的编写方式myType也不应该是myType.GetMethod("SomeMethod")myImplementation.GetType().GetMethod("SomeMethod"))类型,如果它不能替换为:Vector