C#访问通用对象的属性

时间:2010-05-21 14:08:06

标签: c# generics properties types

我有一种方法可以计算每个供应商,客户和制造商所拥有的联系人数量(这是尝试使解释更容易的方案!)

这些模型都是由Linq到SQL类创建的。每个供应商,客户和制造商可能有一个或多个联系人

public int CountContacts<TModel>(TModel entity) where TModel : class
{
    return entity.Contacts.Count();
}

上述当然不起作用,因为'实体'是通用的,并且不知道它是否具有“联系人”属性。有人可以帮忙解决这个问题吗?

5 个答案:

答案 0 :(得分:6)

一种简单的方法是将接口附加到通用中实现的类。

public int CountContacts<TModel>(TModel entity) where TModel : IContacts


interface IContacts
{
   IList<Contact> Contacts {get;} //list,Ilist,ienumerable
}

答案 1 :(得分:3)

强加合同的一种方法是供应商,客户和制造商必须包含Contacts属性,其中包含接口。使每个实体实现一个包含Contacts属性的接口:

interface IContactable
{
   IEnumerable<Contact> Contacts {get;}
}


public int CountContacts<TModel>(TModel entity) where TModel : class, IContactable
{
    return entity.Contacts.Count();
}

答案 2 :(得分:1)

到目前为止所有答案都是正确的,但也应指出代码无法编译的原因是因为TModel类型没有任何共同点。通过指定一个公共基类或接口,他们都可以使用“联系人”属性实现您的代码。

答案 3 :(得分:0)

另一种方法是创建一个仅用于计数的接口。你可以称之为ICountable。

来自MSDN

public interface ICountable<out T>  
{
    int Count{ get; }
}
public class MyCollection : ICountable<string>, ICountable<FileStream>
{  
    int ICountable<string>.Count
    {
        get { return 1; }
    }
    int ICountable<FileStream>.Count
    {
        get { return 2; }
    }
}

答案 4 :(得分:0)

这个问题有几个解决方案。

  • 继承相同的抽象类或实现与实体相同的接口。 (其他人用尽了所有可能的解决办法。)
  • 如果您使用的是.NET 4,则dynamic关键字可能是最便宜的解决方案。

例如:

public int CountContacts(dynamic entity)
{
    return entity.Contacts.Count();
}

这意味着直到运行时才会评估entity,如果您碰巧在没有Contacts属性的对象上调用该方法,它将引发异常。< / p>