Why doesn't the generation limit require casting?

Can anyone shed some light on why calling the DoTest1 method below is a problem?

What is the reason why I need to pass the incoming GridCore object back to the generic type T, although I point out that T comes from GridCore with mine, where is T: GridCore?

thanks

public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { MyTest<MyAlbum> mytest = new MyTest<MyAlbum>(); mytest.DoTest1(new MyAlbum()); mytest.DoTest2(new MyAlbum()); } } public class GridCore { } public class MyAlbum : GridCore { public string Title { get; set; } } public class MyTest<T> where T : GridCore { private List<T> _list = new List<T>(); public void DoTest1(GridCore ma) { //_list.Add(ma); <-- why doesn't this work? _list.Add((T)ma); } public void DoTest2(T ma) { _list.Add(ma); } } 
+4
source share
5 answers

In short, because not all GridCore are T All T are GridCores (due to limitation), and not vice versa.

Imagine the following:

 public class MyChicken : GridCore { public string FavouriteColour { get; set; } } .... new MyTest<MyAlbum>().DoTest1(new MyChicken()); 

If your code has been resolved, you will now have a chicken when you expect an album. Needless to say, people trying to listen to music may not get what they expect.

You probably need to change the signature of DoTest1 to accept only the T that the class is dealing with:

 public void DoTest1(T ma) 

Now MyTest<MyAlbum> will only accept MyAlbum to it DoTest1 .

0
source

If you expect your method to conclude that the GridCore is T (due to a limitation), then it cannot during compilation. That is why you get an error.

Common Methods (C # Programming Guide)

The compiler can infer type parameters based on the method arguments you pass; it cannot deduce type parameters only from a constraint or return value.

+2
source
  private List<T> _list = new List<T>(); 

_list is of type T, and ma

  public void DoTest1(GridCore ma) 

has type GridCore. That is why it does not work.

0
source

C # requires the developer to explicitly cast the object to any of its derived types, since such a cast may fail at runtime. T derived from GridCore. So you can write

 GridCore gridcore = new T(); 

but must explicitly indicate in

 T t = (T)new GridCore(); 
0
source

where T: GridCore means that T is a GridCore , i.e. GridCore is the base type or interface of T

But your list is List<T> , that is, a list of T and T may be a derived class of GridCore .

Suppose T is DerivedGridCore and has an int X field, then should GridCore have an int X field?

Unless you explicitly convert the type (or an implicit statement there), the compiler will not make this assumption because this envelope is not guaranteed.

For more intuitive thinking, a Girafe is Animal , but Animal may not necessarily be just Girafe ; a Tirget is either Animal .

0
source

All Articles