【问题标题】:C# Access the Properties of a Generic ObjectC# 访问通用对象的属性
【发布时间】:2011-02-22 09:21:03
【问题描述】:

我有一个方法可以计算每个供应商、客户和制造商的联系人数量(这是一个尝试让解释更容易的场景!)

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

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

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

【问题讨论】:

    标签: c# generics properties types


    【解决方案1】:

    一种简单的方法是将接口附加到在泛型中实现的类。

    public int CountContacts<TModel>(TModel entity) where TModel : IContacts
    
    
    interface IContacts
    {
       IList<Contact> Contacts {get;} //list,Ilist,ienumerable
    }
    

    【讨论】:

    • +1 除非你不应该返回 List - 最好是 IList 或者甚至是 IEnumerable
    • 这个问题是LINQ to SQL类使用EntitySets来达到这个目的,而EntitySet类型的Contacts属性不会实现接口的属性,所以他必须手动实现它每一堂课。
    【解决方案2】:

    在供应商、客户和制造商必须包含Contacts 属性的情况下,实施合同的一种方法是使用接口。让每个实体实现一个包含Contacts属性的接口:

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

    【讨论】:

      【解决方案3】:

      另一种方法是创建一个仅用于计数的接口。你可以称它为 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】:

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

        【讨论】:

          【解决方案5】:

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

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

          例如:

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-08-03
            • 2013-06-06
            • 2016-05-10
            • 2021-03-05
            • 1970-01-01
            • 2017-11-17
            • 1970-01-01
            相关资源
            最近更新 更多