C# Access the Properties of a Generic Object

左心房为你撑大大i 提交于 2020-01-03 07:28:11

问题


I have a method that counts the number of Contacts each Supplier, Customer and Manufacturer has (this is a scenario to try make explaining easier!)

The models are all created by Linq to SQL classes. Each Supplier, Customer and Manufacturer may have one or more Contacts

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

The above of course doesnt work, because the 'entity' is generic and doesnt know whether it has the property 'Contacts'. Can someone help with how to achieve this?


回答1:


An easy way would be to attach an interface to the classes being implemented in the generic.

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


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



回答2:


One way to impose a contract where Suppliers, Customers and Manufactors must contain a Contacts property is with interfaces. Make each entity implement one interface that contains the Contacts property:

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


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



回答3:


All of the answers so far are correct but should also point out that the reason your code doesn't compile is because the TModel types don't have anything in common. By specifying a common base-class or interface they all implement with your 'Contacts' property your code will work.




回答4:


Another way is to create an interface just for counting. You can call it ICountable.

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



回答5:


There are several solutions to the problem.

  • Inherit the same abstract class or implement the same interface with the entities. (The others exhausted every possible solution with this.)
  • If you are using .NET 4, the dynamic keyword may be the cheapest solution.

For example:

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

This means that entity will not be evaluated until runtime, and if you happen to call the method on an object that doesn't have a Contacts property, it will throw you an exception.



来源:https://stackoverflow.com/questions/2882756/c-sharp-access-the-properties-of-a-generic-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!