6

Can anyone explain why isn't this possible (at least in .Net 2.0):

public class A<T> { public void Method<U>() where U : T { ... } } ... A<K> obj = new A<K>(); obj.Method<J>(); 

with K being the superclass of J

EDIT

I've tried to simplify the problem in order to make the question more legible, but I've clearly overdo that. Sorry!

My problem is a little more specific I guess. This is my code (based on this):

public class Container<T> { private static class PerType<U> where U : T { public static U item; } public U Get<U>() where U : T { return PerType<U>.item; } public void Set<U>(U newItem) where U : T { PerType<U>.item = newItem; } } 

and I'm getting this error:

Container.cs(13,24): error CS0305: Using the generic type Container<T>.PerType<U>' requires2' type argument(s)

8
  • 4
    It is possible in 4.0. Not very useful, because you do not use the type parameter in the signature, but definitely possible. Commented Jun 4, 2012 at 17:16
  • 2
    It does work, even in .NET 2.0. Commented Jun 4, 2012 at 17:20
  • You are absolutely right, I have edited the question. Sorry. Commented Jun 4, 2012 at 17:40
  • Even after edit, the code works perfectly fine. Commented Jun 4, 2012 at 17:44
  • Well, I definitely get the error above. This happens inside Unity which uses Mono compiler. I don't know if it might have something to do with it. Commented Jun 4, 2012 at 18:14

2 Answers 2

8

Actually it is possible. This code compiles and runs just fine:

public class A<T> { public void Act<U>() where U : T { Console.Write("a"); } } static void Main(string[] args) { A<IEnumerable> a = new A<IEnumerable>(); a.Act<List<int>>(); } 

What is not possible is using covariance / contravariance in generics, as explained here:

IEnumerable<Derived> d = new List<Derived>(); IEnumerable<Base> b = d; 
Sign up to request clarification or add additional context in comments.

6 Comments

still, it compiles and works (of course U Item will remain a null at all times - you didnt provide a way to initialize your PertTyp class / its item field)
Please check my latest comment to my question. The initialization is supposed to be done by calling the Set method. obj.Set<J>(jObj) The PerType class should be static. I've removed it while debugging. I've edited the question to add the keyword again.
it still works.. maybe you should provide ur entire complete code?
This is my entire code. There is really nothing more. I've started a new Unity project with just this Class and it gives the same error. Maybe it is a Mono or Unity specific error. I'll try to test it in other platforms. Thanks for your help.
It looks like it can eventually be related with the Mono compiler in Unity. answers.unity3d.com/questions/262475/… I'll try to further confirm this hypothesis tomorrow. Thank you for your help.
|
2

It works for me (VS 2008).

Do you have a problem with a class visibility? (class not public, wrong namespace)

Which error message are you getting?


UPDATE

Given your implementation of Container<T> I can write

class A { } class B : A { } class Test { public void MethodName( ) { var obj = new Container<A>(); obj.Set(new B()); } } 

This works perfectly. Are you sure that B derives from A? Note that for instance List<B> does NOT derive from List<A> (see YavgenyP's answer).


The error message could be a hint, telling you that there exists another Container<T> in another namespace requiring a second type argument for PerType<U, X??? >.

3 Comments

This should be a comment rather than an answer.
This is probably a bug with Mono compiler or Unity. I've asked this same question in their Q&A system. Currently I have no way to test this (I will check it tomorrow at the office), but it seems to be a problem with the compiler: answers.unity3d.com/questions/262475/… Thanks for your insight though.
I've just confirmed it. adding the "Container<T>." prefix solves the problem. it should be caused by some bug in Mono C# compiler.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.