5

コードに話させます。

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>());
        }
    }
}

ThingServiceInstanceが でIThingServiceInstanceありMyThingである場合、 のコレクションに >IThingを追加できないのはなぜですか?ThingServiceInstance<MyThingIThingServiceInstance<IThing>

このコードをコンパイルするにはどうすればよいですか?

4

2 に答える 2

3

ThingServiceInstance<MyThing>は型パラメータで不変であるため、のサブタイプではありませんIThingServiceInstance<IMyThing>IThingServiceInstance<T><T>

ThingServiceInstance<MyThing>のサブタイプを作成したい場合はIThingServiceInstance<IMyThing>T共変でなければなりません。C# では、次のように宣言してこれを行いますIThingServiceInstance<T>

public interface IThingServiceInstance<out T>

編集 ただし、これThingServiceInstance<T>は T のインスタンスのみを返すことができ、それらをメソッド引数として持つことはできないことを意味します (したがって、「out」表記)。

編集2

これが、コードがコンパイルされなかった理由の要点です。指摘したように、あなたはプロパティをThingServiceInstance<T>公開してIThingRepository<T>いるので、それも次のように共変でなければなりません:

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

次のように、プロパティは取得専用である必要があります ( 、 またはのインスタンスのみを返すことができることを思い出してください)。TU<T>

于 2013-11-14T14:13:30.653 に答える
1

インターフェイスのうち 2 つを coariant として宣言し、setter を から削除すると、コンパイルできるようになりますIThingServiceInstance

もちろん、サードパーティのインターフェイスを変更することはできないため、これはあまり役に立ちません。

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

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

IThingRepository<T>が共変を宣言しない場合T

T : A

わからない

IThingRepository<T> : IThingRespository<A>

したがって、あなたは持つことができません

IThingServiceInstance<T> : IThingServiceInstance<A>

ゲッターによって返される型は「互換性」がないためです。

于 2013-11-14T14:15:14.740 に答える