.net - Managed class types as type of type parameter T (Error C2670) -


i want create generic function returning collection of type observablecollection<t>^. callers pass managed class type type parameter t. here 1 of tries of generic function, after explanations of other classes used:

generic<class t>     t:canimal, gcnew()         observablecollection<t>^ getitems(animaltype animaltype, int count)     {         observablecollection<t>^ animals = gcnew observablecollection<t>();         (int = 0; < count; i++)         {             if (animaltype == dog)             {                 cdog^ dog = gcnew cdog(i, count - i);                 //canimal^ dog = gcnew cdog(i, count - i);                 //t dog = gcnew cdog(i, count - i);                 //t^ dog = gcnew cdog(i, count - i);                  animals->add(dog);             }             //else if (animaltype == cat) { ... }             //...         }          return animals;     } 

because tried 1632 ways make function work can't tell why i've implemented :-/

class canimal base class cdog (assume there more animals, too). animaltype enumeration intended used in function above determine correct class type instantiating , adding collection:

ref class canimal { public:     canimal(){}     canimal(int _age) { age = _age; }     int age; };  ref class cdog : canimal { public:     cdog(){}     cdog(int _age, int _other)         :canimal(age), other(_other) {}      int other; };  enum animaltype {     dog,     cat,     fish,     // ... }; 

furthermore there's parent class holding observablecollection's of dogs, cats, , on:

ref class czoo { private:     observablecollection<cdog^>^ dogs;  public:     czoo()     {         dogs = getitems<cdog^>(animaltype::dog, 3);     } }; 

the compiler throws following error:

error c2670: 'system::collections::objectmodel::collection::add' : function template cannot convert parameter 1 type 'cdog ^'

can tell me i'm doing wrong?

!!! solution !!!

based on david yaws' answer ended moving constructor parameters new function called initialize , removed enum animaltypes. final code changed following:

ref class canimal { internal:     virtual void initialize(int _age, int _other)     {         age = _age;         other = _other;     }  public:     int age;     int other; };  ref class cdog : canimal {}; ref class ccat : canimal {};  generic<class t>     t:canimal, gcnew()         observablecollection<t>^ getitems(int count)     {         observablecollection<t>^ animals = gcnew observablecollection<t>();         (int = 0; < count; i++)         {             t animal = gcnew t();             animal->initialize(i, count - i);             animals->add(animal);         }          return animals;     }  ref class czoo { private:     observablecollection<cdog^>^ dogs;     observablecollection<ccat^>^ cats;  public:     czoo()     {         dogs = getitems<cdog^>(3);         cats = getitems<ccat^>(7);     } }; 

if remove stuff not relevant error, here's we've got:

generic<class t> t:canimal, gcnew() observablecollection<t>^ getitems() {     observablecollection<t>^ animals = gcnew observablecollection<t>();      animals->add(gcnew cdog());      return animals; } 

now, happens if invoked getitems<ccat^>()? you're trying put cdog list of ccat, , won't work. that's error message saying: cdog may not able converted t.

if want this, there's couple possible solutions:

  • you return list of canimal instead. cdog valid put list of canimal.
  • you change how initialize list of t.

i'd recommend latter, , this:

generic<class t> t:canimal, gcnew() observablecollection<t>^ getitems(int count) {     observablecollection<t>^ animals = gcnew observablecollection<t>();      (int = 0; < count; i++)     {         t animal = gcnew t();         animal->initialize(i, count-i);         animals->add(animal);     }      return animals; } 
  • because you've got gcnew() constraint, means class has zero-parameter constructor, , you're allowed call using type t.
  • move constructor parameters have method defined on canimal. way can call on t.
  • i removed enum parameter. don't need it; you're specifying animal want via generic.
    • i recommend change regardless of how implement this. otherwise, you'll have consider things getitems<cdog^>(animaltype::cat, 3) should do.

Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

python - build a suggestions list using fuzzywuzzy -