IList <interfacetype>到List <implementsinterfacetype>?</implementsinterfacetype> </interfacetype>

时间:2013-02-13 00:57:54

标签: c# .net generics interface

我有一个广泛实现的接口,它有一个带有特定接口的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)的对象。

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

2 个答案:

答案 0 :(得分: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>ContinuationTriggerITrigger,因此编译器必须允许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>();
}

答案 1 :(得分: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>();
    }
}