Reducing generic parameters

c#, generics

Solution

This is exactly the same situation as with `IEnumerable` / `IEnumerable<T>`. Your weakly typed interface `IFoo` needs to provide a weakly typed `Data`:

public interface IFoo
{
    object Data { get; }
}

public interface IFoo<T> : IFoo
{
    new T Data { get; }
}

then in the implementation one of the will be explicit to favor strongly typed access:

public class IntFoo : IFoo<int>
{
    public int Data { get { return -1; } }

    object IFoo.Data { get { return Data; } }
}

Now you have access to `Data` in either case, although when the actual type `T` is unknown, you have to live with an `object`.

Problem

I'm trying to get an inheritance hierarchy of generics working, and I'm running into a bit of a problem. Here's an example: ``` interface IFoo {} interface IFoo<T> : IFoo { T Data { get; } } class Foo : IFoo<int> { public int Data { get; set; } } interface IBar {} class Bar : IBar { } abstract class LayerOne<T_FOO, T_BAR> where T_FOO : IFoo where T_BAR : IBar {} abstract class LayerTwo<T_FOO> : LayerOne<T_FOO, Bar> where T_FOO : IFoo, new() { protected T_FOO _foo = new T_FOO(); public void Test1() { _foo.Data.Dump();} // Compiler error } class LayerThree : LayerTwo<Foo> { public void Test2() { _foo.Data.Dump();} } ``` I'm trying to get access to `.Data` in the `LayerTwo` class. Clearly, since `IFoo` doesn't have that property, it's going to error. However, if I change they type of `T_FOO` to `IFoo<T>`, then I have to define it and `LayerThree` as: ``` abstract class LayerTwo<T_FOO, T> : LayerOne<T_FOO, Bar> where T_FOO : IFoo<T>, new() { protected T_FOO _foo = new T_FOO(); public void Test1() { _foo.Data.Dump();} } class LayerThree : LayerTwo<Foo, int> { public void Test2() { _foo.Data.Dump();} } ``` But the intent of the concrete `Foo` implementation is that it already knows it's implementing `IFoo<int>`. Is there any way I can get `LayerTwo` to know about the `Data` property without requiring it to be looked up from `Foo` and added to `LayerThree`'s definition? What I'd love is: ``` class LayerThree : LayerTwo<Foo> // Automatically realizes that the second generic is int { public void Test2() { _foo.Data.Dump();} } ``` Update: As it turns out, I was actually trying to implement two contradictory things in my code. The actual `LayerTwo` was trying to keep `T_FOO` generic, but also created an (abstract) method which required a specific type from `IFoo<T>`. So the solution I'm going with is just to use an interface which inherits from `IFoo<T>` and specifies the type, but I'm accepting Ondrej Tucny's answer, since it did solve the problem I asked about.

Original source