Generic method with type constraints or base class parameter

前端 未结 5 1139
清歌不尽
清歌不尽 2021-02-05 04:07

If I write a method accepting a parameter which derives from a BaseClass (or an interface), as far as I know there are two ways to achieve that:

voi         


        
5条回答
  •  醉话见心
    2021-02-05 04:39

    Definitely the example you quoted does not make much difference other than run time execution performance as mentioned in other answers.

    Leaving aside generic collections benefits (performance improvement by avoiding boxing/unboxing for example) which we all aware of and we use frequently - Generics also works great from a consumer perspective. For example, the below code snippet is self explanatory to visualize API usage flexibility from a consumer perspective :

    interface IEntity
    {
       int Id {get;set;}
    }
    
    class Student : IEntity
    {
       int Id {get;set;}
       string SubjectOpted {get;set;}
    }
    
    class Employee : IEntity
    {
       int Id {get;set;}
       string DepartmentName{get;set;}
    }
    
    interface INonGenericRepository
    {
       IEntity Get(int id)
    }
    
    interface IGenericRepository where T:Entity
    {
       T Get(int id)
    }
    
    class NonGenericRepository : IRepository
    {
       public IEntity Get(int id) {/*implementation goes here */
    }
    
    class GenericRepository : IRepository
    {
       public T Get(int id) {/*implementation goes here */
    }
    
    Class NonGenericStudentConsumer
    {
       IEntity student = new NonGenericFRepository().Get(5);
       var Id = student.Id
       var subject = student.SubjectOpted /*does not work, you need to cast */
    }
    
    Class GenericStudentConsumer
    {
       var student = new GenericFRepository().Get(5);
       var Id = student.Id
       var subject = student.SubjectOpted /*works perfect and clean */
    }
    

    A couple of other use cases promoting flexibility while using generics along with constraints are :

    Lets say I want to ensure parameter passed to method implements IAdd and IMultiply and I have class which implements both IAdd,IMulitply like :

        public class BusinessOpeartion where T : IAdd, IMultiply{
        void SomeBusinessOpeartion(T obj) { /*implementation */}
    }
    

    If I need to go via non generic approach, I am forced to create redundant dummy interface like :

    interface IDummy : IAdd, IMultiply
    
     public class BusinessOpeartion{
            void SomeBusinessOpeartion(IDummy obj) { /*implementation */}
        }
    

    Isn't the former approach cleaner?

    Also one more small thing just popped up while typing answer. In case you need to, how would you get new instance for parameter type inside method:

    you cannot do

    IDummy dummy = new IDummy(); /*illegal*/
    

    But with generic you could have; T temp = new T(); provided there is constraint of new()

    Also what if you need a default value for parameter type?

    you cannot do

    var default = default(IDummy); /*illegal*/
    

    But with generic you could have; var default = default(T)

提交回复
热议问题