IList <InterfaceType>到List <ImplementsInterfaceType>?

Oyv*_*son 2 .net c# generics interface

我有一个广泛实现的接口,它有一个具有特定接口的IList.而不是大量的文字,看看这里:

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

public class Language : ILanguage
{
    public Constructor()
    {
        CompletionTriggers = new List<CompletionTrigger>();
    }
}
Run Code Online (Sandbox Code Playgroud)

这基本上就是我想要做的."触发器"是接口的成员,由几种类型实现.但是每种类型都需要一个自定义的ITrigger实现和List(我使用IList,因为它看起来非常方便).

错误显示"缺少一个演员?",但我发现这很奇怪,因为它们都是直接实现IList和ITrigger(List和CompletionTrigger)的对象.

我认为这是一件容易的事情,但是为什么它表现得像这样的一些观点非常感谢!

das*_*ght 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());
Run Code Online (Sandbox Code Playgroud)

由于CompletionTriggers是类型IList<ITriggers>ContinuationTrigger是a 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>();
}
Run Code Online (Sandbox Code Playgroud)