Reputation: 7618
This might be a silly question and I don't really need this for anything but I was just curious...
The best way to describe it is using a example so here it is:
using System;
namespace GenericExample
{
public interface IFoo { }
public interface IFoo2 { }
public class Foo1: IFoo , IFoo2 { }
public class Foo2 : IFoo, IFoo2 { }
public class MyGeneric<T> where T : IFoo , IFoo2, new() { }
internal class Program
{
public static void Main(string[] args)
{
MyGeneric<Foo1> obj1 = new MyGeneric<Foo1>();
MyMethod(obj1);//I can treat obj1 as MyGeneric<T> in MyMethod
MyGeneric<Foo2> obj2 = new MyGeneric<Foo2>();
//But can I use is as MyGeneric<T> in this method???
//MyGeneric<?> obj3 = null;
//obj3 = (MyGeneric<?>)obj1;
//obj3 = (MyGeneric<?>)obj2;
Console.ReadLine();
}
public static void MyMethod<T>(MyGeneric<T> arg) where T : IFoo, IFoo2, new()
{
}
}
}
I don't think it is possible to treat obj1 as MyGeneric< T> in Main
but at the same time it feels strange since I can pass it as a MyGeneric< T> argument
Upvotes: 0
Views: 71
Reputation: 37000
There is no common base-type for MyGeneric and MyGeneric, so I assume the answer is no. In contrast to Java generics in C# are strongly typed types and not just placeholders, so they don´t have anything in common - except a name. However actually they are different types, think of them as just MyGeneric<T1>
being a type Foo
and MyGeneric<T2>
being Bar
.
A way around this is to define a non-generic version of your generic class:
public class Foo1 { }
public class MyNonGeneric { }
public class MyGeneric<T> : MyNonGeneric where T : new() { }
Upvotes: 1
Reputation: 43876
You cannot cast it to MyGeneric<T>
in Main
because in the scope of Main
there is no such type as T
. Actually it's not really clear what you mean by
to treat obj1 as MyGeneric< T> in Main
When passing obj1
to MyMethod
you don't "treat it as MyGeneric<T>
". It is the compiler which infers the type of T
for you. It knows that T
is Foo1
here and translates your call
MyMethod(obj1);
to
MyMethod<Foo1>(obj1);
So the type of the parameter arg
inside of MyMethod
will at runtime also be MyObject<Foo1>
, not an unspecified MyObject<T>
.
Upvotes: 1