为什么这种带有类型约束的泛型方法不能编译?

时间:2012-10-01 17:46:36

标签: c# c#-4.0 generics compilation

我想知道为什么下面的泛型方法不能编译(C#4.0)。我的同事和我都无法弄明白。

编译器抱怨this SelectableRowBase无法转换为TItem,而SelectableRowBase被限制为派生自public class SelectableRowBase { public void AddToSelectedListWhenIsSelectedChanges<TItem> (ObservableCollection<TItem> selectedList) where TItem : SelectableRowBase { // Causes error: // The best overloaded method match for // 'System.Collections.ObjectModel.Collection<TItem>.Add(TItem)' // has some invalid arguments // Argument 1: cannot convert from SelectableRowBase' to 'TItem' Action actionOnSelected = () => selectedList.Add(this); Action actionOnDeselected = () => selectedList.Remove(this); // Compiles and works fine // only difference is the explicit cast Action actionOnSelected = () => selectedList.Add((TItem)this); Action actionOnDeselected = () => selectedList.Remove((TItem)this); } } 。如果我把一个显式的转换一切正常(这是我在源代码管理中检查的),但我想知道为什么编译器在这里抱怨。

这是编译错误吗?我错过了什么吗?

{{1}}

1 个答案:

答案 0 :(得分:4)

不工作是完全合理的。

您正尝试将 base 类型的实例添加到潜在的派生类型的集合中。

这就像试着写:

List<string> strings = new List<string>();
strings.Add(new object());

这会违反类型安全。

基本上,绝对不能保证thisTItem的实例。 可能是演员编译的原因 - 但同样可能不是。那个演员是非常糟糕的主意 - 它将类型安全留给执行时间,这与泛型的目的相反。