繁体   English   中英

使用反射时如何找到接口实例的具体类型?

[英]How to find the concrete type of interface instance when using reflection?

我当前正在尝试创建一个定义为接口的对象的实例。 特别:

public static class A {
    public static IList<string> SampleList { get; set; }

    public void Initialize() { 
        SampleList = new List<string>();
    }
}

// In some other class where I don't have an instance of A.
// This class is in a separate DLL + running in a separate process as A
var propertyInfo = typeof(A).GetProperty("SampleList");
propertyInfo.PropertyType.GetConstructors().Any(); // false
// ^ I would like this to be true

当将SampleList而不是接口(IList)键入为List时,我可以生成一个构造函数并实例化此列表的实例。 我对Arrays和其他未定义为接口的实例具有同样的运气。

我注意到的另一件事是,当我使用List并调用PropertyType.GetInterfaces()时,我会得到8个接口的列表,而当我使用IList实例调用同一命令时,我只会得到3个接口。 一般来说,我得到的信息要少得多。

我想知道是否有可能找出具体的课程本身? 如果是这样,怎么办?

使用GetType()获取具体实例的类型。

    var propertyInfo = typeof(A).GetProperty("SampleList");
    var propertysTypeHasConstructor = propertyInfo.PropertyType.GetConstructors().Any(); // false
    Console.WriteLine(propertysTypeHasConstructor);

    var concreteInstanceType = A.SampleList.GetType();
    var concreteInstanceHasConstructor = concreteInstanceType.GetConstructors().Any(); // true
    Console.WriteLine(concreteInstanceHasConstructor);

输出:

False
True

如果您已经具有可以调用GetType的对象的实例,则John Wu的答案应该起作用。 如果您只有IList<string>类的类型,或者任何接口类型,都将找不到构造函数。 我认为您可以找到的最接近的方法是在AppDomain中搜索程序集,以查找实现该接口并具有默认构造函数的类型。

var interfaceType = typeof(IList<string>);
var ctor = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a =>
    {
        try
        {
            return a.GetTypes();
        }
        catch
        {
            return new Type[0];
        }
    })
    .Select(t => interfaceType.IsGenericType && t.IsGenericType && interfaceType.GetGenericArguments().Length == t.GetGenericArguments().Length && t.GetGenericArguments().All(a => a.GetGenericParameterConstraints().Length == 0) ? t.MakeGenericType(interfaceType.GetGenericArguments()) : t)
    .Where(interfaceType.IsAssignableFrom)
    .SelectMany(t => t.GetConstructors())
    .FirstOrDefault(c => c.GetParameters().Length == 0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM