Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics IAbstract<T> inherits from IAbstract

Tags:

c#

generics

I am trying to achieve something like this:

interface IAbstract
{
    string A { get; }
    object B { get; }
}

interface IAbstract<T> : IAbstract
{
    T B { get; }
}

class RealThing<T> : IAbstract<T>
{
    public string A { get; private set; }
    public T B { get; private set; }
}

So I can do something like this:

RealThing<string> rt = new RealThing<string>();
IAbstract ia = rt;
IAbstract<string> ias = rt;
object o = ia.B;
string s = ias.B;

Is this possible?

like image 618
Cheetah Avatar asked May 18 '14 17:05

Cheetah


People also ask

Is it possible to inherit from a generic type?

An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.

Can a generic class be derived from another generic class?

In the same way, you can derive a generic class from another generic class that derived from a generic interface. You may be tempted to derive just any type of class from it. One of the features of generics is that you can create a class that must implement the functionality of a certain abstract class of your choice.

Can I inherit from generic type C#?

You can't inherit from a Generic type argument. C# is strictly typed language. All types and inheritance hierarchy must be known at compile time. .

Can interface be generic in C#?

You can declare variant generic interfaces by using the in and out keywords for generic type parameters. ref , in , and out parameters in C# cannot be variant. Value types also do not support variance. You can declare a generic type parameter covariant by using the out keyword.


1 Answers

Very nearly. Three things:

  • You should use new in IAbstract<T> to indicate that you know you're hiding an existing member:

    new T B { get; }
    

    But even without that, you'll still only get a warning.

  • You need to implement the IAbstract.B within RealThing, which you should almost certainly do using explicit interface implementation, delegating to the strongly-typed member:

    object IAbstract.B { get { return B; } }
    
  • Within your test code, you need to specify a type argument for RealThing:

    RealThing<string> rt = new RealThing<string>();
    

This is fine, and even a reasonably common pattern for times where you want to be able to get a non-generic form of an interface.

like image 164
Jon Skeet Avatar answered Nov 02 '22 15:11

Jon Skeet