C#访问通用对象的属性

9

我有一个方法,可以计算每个供应商、客户和制造商拥有的联系人数量(这是为了更容易解释而设定的情景!)

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

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

当然,上述方法行不通,因为“实体”是通用的,不知道它是否具有“联系人”属性。可以有人帮忙说明如何实现这一点吗?
5个回答

6
一个简单的方法是将接口附加到在泛型中实现的类上。
public int CountContacts<TModel>(TModel entity) where TModel : IContacts


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

+1 除非你不应该返回List<Contact> - 最好用IList<>或者甚至是IEnumerable<>。 - n8wrl
问题在于,LINQ to SQL 类使用 EntitySets 来实现此目的,而类型为 EntitySet 的 Contacts 属性将不会实现接口的属性,因此他必须在每个类中手动实现它。 - Venemo

3

在IT技术领域,如果要强制供应商、客户和制造商必须包含一个名为Contacts的属性,可以使用接口。只需让每个实体实现一个包含Contacts属性的接口:

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


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

1
到目前为止,所有的答案都是正确的,但也应该指出,你的代码无法编译的原因是 TModel 类型之间没有任何共同点。通过指定一个共同的基类或接口,它们都可以实现你的“Contacts”属性,你的代码将会工作。

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; }
    }
}

0

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

  • 使用相同的抽象类或实现相同的接口来继承实体。(其他人已经尝试了所有可能的解决方案。)
  • 如果您正在使用 .NET 4,dynamic 关键字可能是最便宜的解决方案。

例如:

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

这意味着 entity 直到运行时才会被评估,如果您在没有 Contacts 属性的对象上调用该方法,它将抛出异常。

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