Can't add a concrete instance of a generic interface to a generic collection

Mark Robinson

I'll let the code do the talking:

using System.Collections.Generic;

namespace test
{
    public interface IThing { } // can't change this - it's a 3rd party thing

    public interface IThingRepository<T> where T : class, IThing { } // can't change this - it's a 3rd party thing

    public interface IThingServiceInstance<T>
      where T : class, IThing
    {
        IThingRepository<T> Repository { get; set; }
    }

    public class ThingServiceInstance<T> : IThingServiceInstance<T> where T : class, IThing
    {
        public IThingRepository<T> Repository { get; set; }

    }

    public class MyThing : IThing
    {
    }

    class Test
    {
        public void DoStuff()
        {
            IList<IThingServiceInstance<IThing>> thingServiceInstances = new List<IThingServiceInstance<IThing>>();
            // the following line does not compile. Errors are:
            // 1: The best overloaded method match for 'System.Collections.Generic.ICollection<test.IThingServiceInstance<test.IThing>>.Add(test.IThingServiceInstance<test.IThing>)' has some invalid arguments    C:\TFS\FACE\ResearchArea\ArgonServiceBusSpike\Argon_Service_Bus_Spike_v2\Argon.ServiceLayer\test.cs 31  13  Argon.ServiceGateway
            // 2: Argument 1: cannot convert from 'test.ThingServiceInstance<test.MyThing>' to 'test.IThingServiceInstance<test.IThing>'    C:\TFS\FACE\ResearchArea\ArgonServiceBusSpike\Argon_Service_Bus_Spike_v2\Argon.ServiceLayer\test.cs 31  39  Argon.ServiceGateway
            // Why? ThingServiceInstance is an IThingServiceInstance and MyThing is an IThing
            thingServiceInstances.Add(new ThingServiceInstance<MyThing>());
        }
    }
}

If ThingServiceInstance is an IThingServiceInstance and MyThing is an IThing, why can't I add a ThingServiceInstance<MyThing> to a collection of IThingServiceInstance<IThing>?

What can I do to make this code compile?

dcastro

ThingServiceInstance<MyThing> is NOT a subtype of IThingServiceInstance<IMyThing>, because IThingServiceInstance<T> is invariant in its type parameter <T>.

If you wanna make ThingServiceInstance<MyThing> a subtype of IThingServiceInstance<IMyThing>, then T has to be covariant. In C#, you do that by declaring IThingServiceInstance<T> as such:

public interface IThingServiceInstance<out T>

Edit This, however implies that ThingServiceInstance<T> can only return instances of T, but never have them as method arguments (hence the "out" notation).

Edit2

This is the gist of why your code wasn't compiling. As pointed out, since your ThingServiceInstance<T> exposes an IThingRepository<T> property, that too has to be covariant like so:

public interface IThingRepository<out T> where T : class, IThing { }

As follows, your property has to be get-only (remember, you can only return instances of T, or U<T> for that matter).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Can't add a concrete instance of a generic interface to a generic collection

From Dev

Can't convert from Abstract<Generic> to Concrete:Abstract<Concrete:Generic>

From Dev

Why can't I convert concrete type to interface while using generic constraints

From Dev

Can't convert concrete type to generic version of its Interface in C#

From Dev

Reading concrete class property within a generic method that doesn't get generic type instance

From Dev

Can you specify a generic type that subclasses another generic type _and_ a concrete interface?

From Dev

extend a concrete instance of a generic type in Swift

From Dev

extend a concrete instance of a generic type in Swift

From Dev

Get Concrete Implementation of Interface with Generic Parameter

From Dev

Concrete class which inherites a generic interface

From Dev

Why can't a Java Generic implement an Interface?

From Dev

Can't create generic for an interface implementor

From Dev

Can't create generic for an interface implementor

From Dev

Typescript Can't implement generic function interface

From Dev

Generic type interface that accepts both types of Collection<T> and <T>

From Dev

Using an Interface for Collection<> generic type

From Dev

Using an Interface for Collection<> generic type

From Dev

Why can I not infer an interface from a constrained generic collection?

From Dev

Concrete class doesn't compile with a generic identifier

From Dev

Accessing instance of generic collection from items in collection

From Dev

Generic and Non-Generic Interface - List of T

From Dev

Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?

From Dev

How can I add an instance of a generic type to a list in Kotlin

From Dev

Add JSON data to a generic collection

From Dev

Is there any hack to know the actual concrete class of the generic of an instance at runtime?

From Dev

Unity 3.5: Retrieve concrete implementation by its open generic interface

From Dev

Does injecting a generic interface with concrete types defeat the purpose of dependency injection?

From Dev

Instance of T (generic type) in Java

From Dev

Check if a generic T implements an interface

Related Related

  1. 1

    Can't add a concrete instance of a generic interface to a generic collection

  2. 2

    Can't convert from Abstract<Generic> to Concrete:Abstract<Concrete:Generic>

  3. 3

    Why can't I convert concrete type to interface while using generic constraints

  4. 4

    Can't convert concrete type to generic version of its Interface in C#

  5. 5

    Reading concrete class property within a generic method that doesn't get generic type instance

  6. 6

    Can you specify a generic type that subclasses another generic type _and_ a concrete interface?

  7. 7

    extend a concrete instance of a generic type in Swift

  8. 8

    extend a concrete instance of a generic type in Swift

  9. 9

    Get Concrete Implementation of Interface with Generic Parameter

  10. 10

    Concrete class which inherites a generic interface

  11. 11

    Why can't a Java Generic implement an Interface?

  12. 12

    Can't create generic for an interface implementor

  13. 13

    Can't create generic for an interface implementor

  14. 14

    Typescript Can't implement generic function interface

  15. 15

    Generic type interface that accepts both types of Collection<T> and <T>

  16. 16

    Using an Interface for Collection<> generic type

  17. 17

    Using an Interface for Collection<> generic type

  18. 18

    Why can I not infer an interface from a constrained generic collection?

  19. 19

    Concrete class doesn't compile with a generic identifier

  20. 20

    Accessing instance of generic collection from items in collection

  21. 21

    Generic and Non-Generic Interface - List of T

  22. 22

    Why can't I extend an interface "generic method" and narrow its type to my inherited interface "class generic"?

  23. 23

    How can I add an instance of a generic type to a list in Kotlin

  24. 24

    Add JSON data to a generic collection

  25. 25

    Is there any hack to know the actual concrete class of the generic of an instance at runtime?

  26. 26

    Unity 3.5: Retrieve concrete implementation by its open generic interface

  27. 27

    Does injecting a generic interface with concrete types defeat the purpose of dependency injection?

  28. 28

    Instance of T (generic type) in Java

  29. 29

    Check if a generic T implements an interface

HotTag

Archive