簡體   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