Click here to Skip to main content
14,634,606 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hi!

I'm trying to figure out Generics

Here's the test code (it's my own)

I cannot realize why the error occuires "Cannot implicitly convert 'T' as 'int'"
the "left" variable is definitely INT and the cast like (int)left is not useful
Could you please suggest
public class MyClass<t> //where T : IEnumerable<t>
{
    static Int32 iLeft;
    static string sLeft;

    public MyClass(T left)
    {
        if(typeof(T).Equals(typeof(Int32)))
        {
            <b>MyClass<t>.iLeft =left;     //the error - <b>Cannot implicitly convert 'T' as 'int'</b> </t></b>
        }
    }

    public static implicit operator MyClass<t>(T left)
    {
        return new MyClass<t>(left);
   }

    public static implicit operator Int32(MyClass<t> left)
    {
        if(left.Equals(typeof(Int32)))
        {
            return MyClass<t>.iLeft;
        }
        else
        {
            return -1;
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        MyClass<int32> r = 5;
    }
}


[edit]Code block added - OriginalGriff[/edit]

What I have tried:

Jeffrey Richter C#, articles in codeproject
Posted
Updated 10-Aug-16 3:32am
v3

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

The compiler doesn't know what "T" is as that is defined by the calling code - it could be anything, a string, a double, an Animal class. So it can't allocate it to your int parameter.

You'd have to cast "T" into int before you assign it to your property. However, your code can only work if "T" is int so this is a pointless use of generics, if a generic class can only support one type you may as well not use generics at all and use strong types instead.

Updated;

I'd write it something like below, however again I stress that the use of generics is a bit pointless here. It's usually ok to deal with types completely generically, or to deal with base types, but writing per-type exceptions is just bad practice.

public class MyClass<T>
{
    public T iLeft { get; set; }
    public string sLeft { get { return this.iLeft.ToString(); } }

    public MyClass(T left)
    {
        iLeft = left;
    }

    public static implicit operator MyClass<T>(T left)
    {
        return new MyClass<T>(left);
    }

    public static implicit operator Int32(MyClass<T> left)
    {
        if (typeof(T).Equals(typeof(Int32)))
        {
            return (int)(object)left.iLeft;
        }
        else
        {
            return -1;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass<int> r = 5;
        MyClass<int> x = 10;

        Console.WriteLine("r after creation = " + r.iLeft);
        Console.WriteLine("x after creation = " + x.iLeft);

        r = 3;

        Console.WriteLine("r after assignment = " + r.iLeft);

        int rAsInt = r;
        int xAsInt = x;

        Console.WriteLine("rAsInt = " + rAsInt);
        Console.WriteLine("xAsInt = " + xAsInt);

        int y = x * 2;

        Console.WriteLine("x * 2 = " + y);

        int z = r * x;

        Console.WriteLine("r * x as ints= " + z);

        MyClass<int> classMult = r * x;

        Console.WriteLine("r * x as MyClass<int> = " + classMult);        
        Console.ReadLine();
   
v2
Comments
OriginalGriff 10-Aug-16 9:33am
   
:thumbsup:
po_saa 10-Aug-16 9:53am
   
Thank you for the answer.
Actually it works just with "int" for training purposes only

>>The compiler doesn't know what "T"
Nevertheless while runtime I create the MyClass<int> when "r" is declared and the constructor MyClass correctly accepts the int

So. Could you please suggest
how to correct the code? (for awhile to work just with int)
Richard Deeming 10-Aug-16 10:02am
   
if (typeof(T) == typeof(int))
{
   iLeft = (int)(object)left;
}
po_saa 10-Aug-16 10:11am
   
wow! great!
thanks alot!
BillWoodruff 10-Aug-16 10:32am
   
+5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100