2

広く実装されているインターフェイスがあり、特定のインターフェイスを持つIListがあります。たくさんのテキストの代わりに、ここを見てください:

interface ILanguage
{
    IList<ITriggers> CompletionTriggers { get; set; }
}

public class Language : ILanguage
{
    public Constructor()
    {
        CompletionTriggers = new List<CompletionTrigger>();
    }
}

これは基本的に私がやろうとしていることです。「トリガー」は、いくつかのタイプによって実装されるインターフェースのメンバーです。ただし、各タイプには、カスタムITrigger実装とListが必要です(非常に便利なようにIListを使用しています)。

エラーには「キャストがありませんか?」と表示されますが、どちらもIListとITrigger(ListとCompletionTrigger)の両方を直接実装するオブジェクトであるため、奇妙なことに気付きます。

これは簡単なことだと思いますが、なぜこのように動作するのかについてのいくつかのポイントは高く評価されています!

4

2 に答える 2

5

これは簡単なことだと思います

簡単ではない。少なくともそれほど簡単ではありません。これが許可されない理由は、例を挙げて説明するのが一番です。あなたが提案するような割り当てを行うことが許可されたとします:

// Let's make another trigger unrelated to CompletionTrigger
class ContinuationTrigger : ITrigger {
}
// This is allowed
List<CompletionTrigger> myTriggers = new List<CompletionTrigger>();
// THIS WILL NOT WORK (but let's pretend that it does)
IList<ITriggers> CompletionTriggers = myTriggers;
// Here comes trouble:
CompletionTriggers.Add(new ContinuationTrigger());

CompletionTriggersは 型IList<ITriggers>でありContinuationTriggerであるため、ITriggerコンパイラはAdd呼び出しを許可する必要があります。myTriggersしかし、これはとして作成されたコレクションである に継続トリガーを配置することになりList<CompletionTrigger>、これは絶対に許可されません。

これを克服する限り、いくつかの選択肢があります。最も単純な方法はITrigger、オブジェクトの作成時にのみ区別して、オブジェクトを同等に扱うことです。これは注意が必要な場合があり、場合によっては複数のディスパッチが必要になります。

別のオプションは、次の要素を取得および設定するための一般的なカバーを作成することですCompletionTriggers

void SetCompletionTriggers<T>(IList<T> triggers) where T : ITrigger {
    CompletionTriggers = triggers.Cast<ITrigger>().ToList();
}
IEnumerable<T> GetCompletionTriggers<T>() where T : ITrigger {
    return CompletionTriggers.Cast<T>();
}
于 2013-02-13T01:20:06.743 に答える
0

リストを次のように定義するIList<ITriggers>場合は、新しいものにする必要があると思いますnew List<ITriggers>

特定のタイプのリストを本当に作成したい場合は、インターフェイスをジェネリックにすることができます

interface ITriggers
{
}

class CompletionTrigger : ITriggers
{
}

interface ILanguage<T> where T: ITriggers
{
    List<T> CompletionTriggers { get; set; }
}

class Language : ILanguage<CompletionTrigger>
{
    public List<CompletionTrigger> CompletionTriggers { get; set; }
    public Language()
    {
        CompletionTriggers = new List<CompletionTrigger>();
    }
}
于 2013-02-13T01:33:28.010 に答える