2013-01-02 55 views
1

我想對某個類型參數T使用反射來獲取其構造函數。在C#中使用反射來獲取接受類型或派生類型的構造函數

我想要得到的構造函數是接受某些類型ISomeType或從中派生的任何類型的構造函數。

例如:

public interface ISomeType 
{ 
} 

public class SomeClass : ISomeType 
{ 
} 

我想找到構造,要麼接受ISomeType,SomeClass的,或任何其他ISomeType派生類。

有沒有簡單的方法來實現這一目標?

回答

4

你可以做這樣的事情:

public List<ConstructorInfo> GetConstructors(Type type, Type baseParameterType) 
{ 
    List<ConstructorInfo> result = new List<ConstructorInfo>(); 

    foreach (ConstructorInfo ci in type.GetConstructors()) 
    { 
    var parameters = ci.GetParameters(); 
    if (parameters.Length != 1) 
     continue; 

    ParameterInfo pi = parameters.First(); 

    if (!baseParameterType.IsAssignableFrom(pi.ParameterType)) 
     continue; 

    result.Add(ci); 
    } 

    return result; 
} 

相當於擁有了

public IEnumerable<ConstructorInfo> GetConstructors(Type type, Type baseParameterType) 
{ 
    return type.GetConstructors() 
      .Where(ci => ci.GetParameters().Length == 1) 
      .Where(ci => baseParameterType.IsAssignableFrom(ci.GetParameters().First().ParameterType) 
} 

當你添加一些LINQ魔術

+1

您可以使用'yield return'來代替在第一個示例中使用結果保留。 –

+0

@AshBurlaczenko:我當時想「儘可能做到香草」。 – SWeko

+0

謝謝,這個工程。我的壞處是爲ParameterInfo實例而不是ParameterType做了一個GetType(),呵呵! –

0

基類不知道自己的devived類,這就是爲什麼你不能得到派生類的ctors。你必須從集中的所有類和發現接受它們之間構建函數

1

你可以這樣說:

Type myType = ... 
var constrs = myType 
    .GetConstructors() 
    .Where(c => c.GetParameters().Count()==1 
    && c.GetParameters()[0].ParameterType.GetInterfaces().Contains(typeof(ISomeType)) 
    ).ToList(); 
if (constrs.Count == 0) { 
    // No constructors taking a class implementing ISomeType 
} else if (constrs.Count == 1) { 
    // A single constructor taking a class implementing ISomeType 
} else { 
    // Multiple constructors - you may need to go through them to decide 
    // which one you would prefer to use. 
} 
相關問題