1

私はこのジェネリッククラスを持っています

public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
....
}

そして私はこの派生クラスを持っています

public class MessageExportCommand : BaseExportCommand<Message> 
{
 .....
}

メッセージがEdittableEntityから継承する場所

public class Message : EditableEntity
{
...
}

さて、私がこの声明を行おうとすると

BaseExportCommand<EditableEntity> myValue = new MessageExportCommand ();

次のエラーが発生しました:

Cannot convert type 'MessageExportCommand' to 'BaseExportCommand<EditableEntity>'   

なぜですか?

4

2 に答える 2

8

理由はありますか?

はい。あなたのジェネリック型は で共変ではありませんT

そうあるべきかどうかは、すぐにはわかりません。たとえば、次のようになっているとします。

public abstract class BaseExportCommand<T> where T : EditableEntity, new()
{
    public abstract DoSomethingWithEntity(T entity);
}

次に、次のように記述できるとします。

BaseExportCommand<EditableEntity> myValue = new MessageExportCommand();
EditableEntity entity = new SomeEditableEntity();
myValue.DoSomethingWithEntity(entity);

...一方MessageExportCommand、期待するだけですDoSomethingWithEntity(Message)

からの出力Tとしてのみ使用する場合は安全ですが、残念ながら C# ではクラスの共変型パラメーターを宣言できません。インターフェイスとデリゲートのみです。したがって、潜在的に次のように書くことができます。BaseExportCommand<T>

// Note the "out" part, signifying covariance
public interface IExportCommand<out T> where T : EditableEntity, new()

それで:

IExportCommand<EditableEntity> = new MessageExportCommand();

...しかし、インターフェースで宣言されたメンバーによって異なります。「入力」位置で使用しようとするとT、コンパイラはそれを認識し、共変宣言を防ぎますT

詳細については、MSDN の Variance in Generic Types と、このトピックに関する Eric Lippert のブログ投稿を参照してください(落ち着いてリラックスしてください。読むべきことがたくさんあります)。

于 2012-11-19T22:34:51.170 に答える
1

Tこれは、共変として宣言した場合にのみ機能します。

public abstract class BaseExportCommand<out T> where T : EditableEntry, new()
{
    ...
}

共変とは、Tまたはから継承する任意のクラスに使用できることを意味しますT

共変性と反変性に関するFAQも参照してください。

于 2012-11-19T22:33:28.837 に答える