buckley
buckley

Reputation: 14040

Implementing an interface with a generic constraint

Bit surprised why this does not work

Is this a limitation of the compiler or does it make good sense not to support it?

public class Class1<T> : IInterface
    where T : Test2
{
    public T Test { get; private set; }
}

public class Test2
{
}

internal interface IInterface
{
    Test2 Test { get; }
}

The error I get is

'ClassLibrary1.Class1<T>' does not implement interface member 'ClassLibrary1.IInterface.Test'. 
'ClassLibrary1.Class1<T>.Test' cannot implement 'ClassLibrary1.IInterface.Test' because it does not have the matching return type of 'ClassLibrary1.Test2'.

Upvotes: 16

Views: 8058

Answers (5)

cuongle
cuongle

Reputation: 75306

For more corrective, implement interface explicitly:

public class Class1<T> : IInterface
where T : Test2
{
    public T Test { get; private set; }

    Test2 IInterface.Test
    {
        get { ... }
    }
}

Then you can avoid compiled error.

Upvotes: 13

Kirill Bestemyanov
Kirill Bestemyanov

Reputation: 11964

Interface say that property Test is of Test2 Type. In your implementation Class1 property Test is of some class that inherited of Test2 but not exactly it. To do what you want, you need write something like this:

public class Class1<T> : IInterface
    where T : Test2
{
    private T _test;
    public Test2 Test { get{return _test} }
}

public class Test2
{ 
}

internal interface IInterface 
{
    Test2 Test { get; }
}

Upvotes: 1

Charleh
Charleh

Reputation: 14012

Is it feasible for you to make your interface generic e.g.

public class Class1<T> : IInterface<T>
    where T : Test2
{ 
    public T Test { get; private set; } 
} 

public class Test2 
{ 
} 

internal interface IInterface<T>
{ 
    T Test { get; } 
} 

Or are you trying to avoid generics on the interface (there are good reasons for that too!)

Upvotes: 1

cauon
cauon

Reputation: 513

Change your interface to this and it will compile:

public class Class1<T> : IInterface<T>
    where T : Test2
{
    public T Test { get; private set; }
}

public class Test2
{
}

internal interface IInterface<T>
    where T : Test2
{
    T Test { get; }
}

Upvotes: 4

Jon
Jon

Reputation: 437336

Since T can be any type derived from Test2, Class1 does not implement IInterface exactly.

More generally, it is not possible to implement an interface by returning a covariant type:

interface IFoo
{
    object Bar { get; }
}

class Broken : IFoo
{
    string Bar { get; } // you cannot expect to implement IFoo this way!
}

Upvotes: 5

Related Questions