Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I am (trying) to learn about generics and I thought I understood them. I have the following code for the generic class:

    /// <summary>
    /// generics
    /// </summary>
    class Point<T> where T : IConvertible
    {
        public T X;


        NumberFormatInfo nf = NumberFormatInfo.CurrentInfo;

        public double Subtract(Point<T> pt)
        {
            return (X.ToDouble(nf) + pt.X.ToDouble(nf));
        }

    }

and in the Main(), I can create the objects fine:

        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 ints, doubles or even strings, but I can't run on mixed, which I thought I would be able to because of the .ToDouble conversion.

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 as I am simply trying to understand/learn generics, so I would just like to understand what is wrong here and why it wouldn't work.... The actual method is not that important/will not be used.

like image 526
Wil Avatar asked Feb 25 '23 00:02

Wil


2 Answers

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

You need to give Subtract a separate generic parameter so that it can take a Point<U> for any U.

like image 63
SLaks Avatar answered Feb 27 '23 15:02

SLaks


Your method signature:

public double Subtract(Point<T> pt)

Asks for a Point of generic type T, which matches the generic type in your class definition:

class Point<T> where T : IConvertible

That means it's asking for the same type.

You can specify a different generic type to allow it to 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 you pass, you can call your method in the same way without needing to specify the type:

Console.WriteLine(pt.Subtract(pt2)); // As opposed to pt.Subtract<double>(pt2)
like image 23
BoltClock Avatar answered Feb 27 '23 14:02

BoltClock