检查C#中的T泛型类型是否具有属性S(泛型)。

11

类 A

class A{
...
}

B类

 class B:A{
    ...
 }

类 C

 class C:A{
    B[] bArray{get;set;}
 }

我希望检查T是否具有S的属性类型,创建S的实例并将其赋值给该属性:
public Initial<T,S>() where T,S : A{
   if(T.has(typeof(S))){
      S s=new S();
      T.s=s;
   }
}

如果T具有多个类型为S的属性,该怎么办? - Ralf
如果这就是该方法的全部内容,可以使用“where T,S:C”作为替代。 - Chris Wohlert
@Ralf 谢谢提醒,我没想到 :-( - Mohammad Javad
2个回答

13
最好且最简单的做法是使用接口实现此功能。
public interface IHasSome
{
    SomeType BArray {get;set;}
}

class C:A, IHasSome
{
    public SomeType BArray {get;set;}
}

然后你可以在通用方法中对对象进行转换:

public T Initial<T,S>() where T : new() where S : SomeType, new()
{
    T t = new T();

    if (t is IHasSome)
    {
        ((IHasSome)t).BArray = new S();
    }

    return t;
}

如果不适合,您可以使用反射来检查属性并检查它们的类型。相应地设置变量。

我希望Initial方法返回T而不是void。否则我看不出它有什么用处... - Zohar Peled
@ZoharPeled 同意。原帖没有指定返回类型,所以我只插入了 void - Patrick Hofman
是的,我刚刚在回答关于那个问题的评论,但你发了你的答案,所以我决定在这里发表评论。除此之外,我同意 - 接口是这里的最佳选择。 - Zohar Peled

6

我同意@PatrickHofman的做法更好,但如果你想要更通用的方式来为类型的所有属性创建新实例,你可以使用反射:

public T InitializeProperties<T, TProperty>(T instance = null) 
    where T : class, new()
    where TProperty : new()
{
    if (instance == null)
        instance = new T();

    var propertyType = typeof(TProperty);
    var propertyInfos = typeof(T).GetProperties().Where(p => p.PropertyType == propertyType);

    foreach(var propInfo in propertyInfos)
        propInfo.SetValue(instance, new TProperty());

    return instance;
}

然后:

// Creates a new instance of "C" where all its properties of the "B" type will be also instantiated
var cClass = InitializeProperties<C, B>();

// Creates also a new instance for all "cClass properties" of the "AnotherType" type
cClass = InitializeProperties<C, AnotherType>(cClass);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接