Why can't I run the following method from a shared object?

I (try) to find out about generics, and I thought I understood them. I have the following code for a general class:

/// <summary> /// generics /// </summary> class Point<T> where T : IConvertible { public TX; NumberFormatInfo nf = NumberFormatInfo.CurrentInfo; public double Subtract(Point<T> pt) { return (X.ToDouble(nf) + pt.X.ToDouble(nf)); } } 

and in Main() I can create objects in order:

  Point<int> pt = new Point<int>(); Point<double> pt2 = new Point<double>(); Point<string> pt3 = new Point<string>(); pt.X = 10; pt2.X = 10; pt3.X = "10"; 

Now I can run the Subtract method on two int s, double or even string s, but I can’t work on mixed, and I thought I could because of .ToDouble .

If I try to run Console.WriteLine(pt.Subtract(pt2)); I get the following errors:

 Error 1 The best overloaded method match for Date.Point<int>.Subtract(Date.Point<int>)' has some invalid arguments Error 2 Argument 1: cannot convert from 'Date.Point<double>' to 'Date.Point<int>' 

The code itself is not so important, because I'm just trying to understand / learn generalizations, so I just would like to understand what is wrong here and why this will not work ... The actual method is not so important / will not be used.

+4
source share
3 answers

Your method signature:

 public double Subtract(Point<T> pt) 

queries Point generic type T , which matches the typical type in your class definition:

 class Point<T> where T : IConvertible 

This means that it is requesting the same type.

You can specify a different generic type so that it can mix different types:

 public double Subtract<U>(Point<U> pt) where U : IConvertible { return (X.ToDouble(nf) + pt.X.ToDouble(nf)); } 

Note, however, that since the actual type of U can be inferred from the Point<U> argument that you pass, you can call your method in the same way without specifying the type:

 Console.WriteLine(pt.Subtract(pt2)); // As opposed to pt.Subtract<double>(pt2) 
+1
source

Your Subtract method accepts Point<T> .
T is the type parameter of your class, which means that it can only accept a Point the same type.

You need to provide Subtract separate generic parameter so that it can accept Point<U> for any U

+6
source

Type T must be the same in the class declaration and method:

 class Point<T> where T : IConvertible { public double Subtract(Point<T> pt) 

You can enter a second general parameter:

 class Point<T> where T : IConvertible { public double Subtract<T2>(Point<T2> pt) where T2 : IConvertible 
+1
source

Source: https://habr.com/ru/post/1340616/


All Articles