2

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

编译器抱怨thiswhich is aSelectableRowBase不能转换为 a 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);
    }
}
4

1 回答 1

4

它不工作是完全合理的。

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

这就像试图写:

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

这将违反类型安全。

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

于 2012-10-01T17:49:29.430 回答