Melursus
Melursus

Reputation: 10578

.Net c# Generic issue

Here is an example :

public class B<T> {}
public class D : B<int> {}
public class A<T, S> where T : B<S> {}
public class C : A<D, int> {}

public class Test1
{
    public class test1
    {
        A<D, int> t = new C();
    }
}

What I would like do to is in declaring class C, only say : C : A<D>. Why I need to repeat int ? Because int is already a part of D.

Same in the test1 method. I would like to write : A<D> t = new C();

How, can I achieve that ?

UPDATE

Here with more realistic class names :

public class MyModel<T> { }
public class MyTrueModel : MyModel<int> { }

public class MyManager<T,S> where T : MyModel<S> { }
public class MyTrueManager : MyManager<MyTrueModel, int> { }

public class Test1
{
    public class test1
    {
        MyManager<MyTrueModel, int> t = new MyManager<MyTrueModel, int>();
    }
}

All the problem come from the class MyManager. If I was able to do something like : MyManager<T> where T : MyModel it'd would be great.

Upvotes: 1

Views: 185

Answers (4)

jason
jason

Reputation: 241585

Here's your code:

public class B<T> {}
public class D : B<int> {}
public class A<T, S> where T : B<S> {}
public class C : A<D, int> {}
public class Test1 {
    public class test1 {
        A<D, int> t = new C();
    }
}

Here's equivalent code:

public class B<T> {}
public class D : B<int> {}
public class A<U, V> where U : B<V> {}
public class C : A<D, int> {}
public class Test1 {
    public class test1 {
        A<D, int> t = new C();
    }
}

The point is that the U in A<U, V> is a dummy. When you replace U with T (and V with S) and write A<T, S> the T does not refer to the same T in B<T>. This is why you must use C : A<D, int>. If you were to only write A<D> the compiler does not know (and nor should it; see my comment below on free versus unbound variables) that you want to use int for T in B<T>.

All the problem come from the class MyManager. If I was able to do something like : MyManager<T> where T : MyModel it's would be great.

This is not possible. MyModel is not declared as a type. Only MyModel<T> is a type. More specifically, it is an unbounded generic type. When you specify a type argument (e.g., MyModel<int>) then it will be a constructed type.

At this risk of confusing you further (on this admittedly confusing issue), it might help you read about free and unbounded variables.

Upvotes: 3

Seth
Seth

Reputation: 46403

A<D> t = new C(); won't work because you have previously declared A to require two generic parameters.

You could declare something like:

class A2<T> : A<T, int> {}

Then (I think) you could achieve A2<D> t = new C();, but I'm assuming that the compiler is smart enough to realize that A2 is compatible with C ... it may not be.

Is this an experiment? Looks like you might have trouble figuring out what this is supposed to do 6 months from now (or even 2 months from now :)

Upvotes: 0

Anon.
Anon.

Reputation: 60008

Declare A as:

public class A<T> where T : B<S>

Should work, but I don't have a compiler on me so I can't say for sure.

Upvotes: -1

Mike Chaliy
Mike Chaliy

Reputation: 26648

Probably I missunderstood your question. But if you do not need int. Just use D.

public class B<T> { }
public class D : B<int> { }
public class A<T> where T : D { }
public class C : A<D> { }
public class Test1 { public class test1 { A<D> t = new C();    } }

Upvotes: 0

Related Questions