c# - convert inherited to generic base -


can explain why conversion in return in switch statement doesn't compile in .net 4? i've updated example more accurate situation. factory isn't generic actually.

even casting "as baseproductprocessor" not work if i'm passing in base product (that's standardproduct). if explicitly pass standardproduct type factory, it's ok - have defined product type in calling methods anyway :|

how around this?

using system; using microsoft.visualstudio.testtools.unittesting;  namespace testing {     [testclass]     public class test     {         [testmethod]//fails         public void testfactorymethodwithbasetypepassed()         {             product product = new testing.standardproduct();             var pp = new testing.productprocessorfactory().create(product);             assert.isnotnull(pp);//fails because t coming create wasn't derived type         }         [testmethod]//passes         public void testfactorymethodwithexacttype()         {             var pp = new testing.productprocessorfactory().create(new testing.standardproduct());             assert.isnotnull(pp);         }     }     public abstract class baseproductprocessor<t> t : product     {         public t product { get; set; }         public baseproductprocessor(t product)         {             product = product;         }     }      public class standardproductprocessor : baseproductprocessor<standardproduct>     {         public standardproductprocessor(standardproduct product)             : base(product)         {         }     }      public class productprocessorfactory     {         public productprocessorfactory()         {         }          public baseproductprocessor<t> create<t>(t product) t : product         {             switch (product.producttype)             {                 case producttype.standard:                     var spp = new standardproductprocessor(product standardproduct);                     return spp baseproductprocessor<t>;//nulls if t passed product.. how explicitly t standardproduct right here in factory method it's centralized?             }             return null;// spp baseproductprocessor<t>;         }     }      public class product     {         public producttype producttype { get; set; }     }      public enum producttype     {         standard,         special     }      public class standardproduct : product     {     } } 

well, here want achieve covariance of template parameter. not possible base classes, possible intefaces. so, suggest replace abstract class baseproductprocessor<t> interface:

public interface ibaseproductprocessor<out t> t : product // out marks argument covariant {     t product { get;  } // absense of setter crusial here - otherwise you'll violate type safety } 

standartprocessor:

public class standardproductprocessor : ibaseproductprocessor<standardproduct>  {     public standardproductprocessor(standardproduct product)     {         product = product;     }      public standardproduct product { get; private set; } } 

and this, modify factory function following: public class productprocessorfactory { public productprocessorfactory() { }

    public ibaseproductprocessor<t> create<t>(t product) t : product     {         switch (product.producttype)         {             case producttype.standard:                 var spp = new standardproductprocessor(product standardproduct);                  return spp ibaseproductprocessor<t>;//no more nulls!         }         return null;     } } 

with modifications, both of tests pass.

if want learn more covariance , contravariance(out , in keywords in c#), recommend excellent series in eric lippert's blog (start bottom ones)


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -