我有一个广泛实现的接口,它有一个带有特定接口的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)的对象。
我认为这是一件容易的事情,但是为什么它表现得像这样的一些观点非常感谢!
答案 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>
且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>();
}
答案 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>();
}
}