tags:

views:

90

answers:

1

Hi,

I have a question about .net generics. Consider the following code:

public abstract class Test<TKey>
{
    TKey Key { get; set; }
}

public class Wrapper<TValue, TKey>
    where TValue : Test<TKey>
{
    public TValue Value { get; set; }
}

Now, when using this code, I could do something like this:

Wrapper<Test<int>, int> wrapper = new Wrapper<Test<int>, int>();

The int type parameter has to be provided twice. Is it possible to modify the Wrapper definition, to require TValue to be a generic type, and use this 'nested' generic type parameter insted of the TKey type parameter?

+1  A: 

I'd say this depends on whether or not you really need to expose your Value property as a specific TValue where TValue derives from Test<T>. In other words, do you need to expose functionality available only to derived classes, or could you simply expose a Test<T>, with all the functionality of the base class?

In the latter case, you could simplify your class definition as:

public class Wrapper<TKey>
{
    public Test<TKey> Value { get; set; }
}

As for the precise functionality you're seeking: I don't believe anything quite like that is available in the current version of C#.

That said, another option in your case might be to actually use your Wrapper class itself as a base class:

public abstract class Test<TKey>
{
    TKey Key { get; set; }
}

public abstract class Wrapper<TValue, TKey>
    where TValue : Test<TKey>
{
    public TValue Value { get; set; }
}

public class TestWrapper<TKey> : Wrapper<Test<TKey>, TKey>
{ }

// ... some code somewhere
var tw = new TestWrapper<int>();
Test<int> value = tw.Value;
Dan Tao
`Test` is an abstract class though, based on comments in a deleted question you can't see quite yet (if I remember my rep limits!), the OP wants classes that inherit from `Test<T>`, not the actual class itself. He wants something like `Wrapper<Test, int>` or `Wrapper<TestChild, int>` and `TestChild` *actually* be `TestChild<T>`...I believe the answer is the same though, this doesn't exist. But hey, maybe there's a way to get this I'm unaware of...I'm sure the IL can do it, but not sure about C#.
Nick Craver