2

以下のジェネリックメソッドがコンパイルされない理由を知りたいです(C#4.0)。私の同僚も私もそれを理解することはできません。

thisコンパイラは、これをから派生するように制約SelectableRowBaseされているaに変換できないと文句を言います。明示的なキャストを配置すると、すべてが機能します(そして、それがソース管理でチェックしたものです)が、コンパイラがここで不平を言っている理由を知りたいです。TItemSelectableRowBase

それはコンパイラエラーですか?私は何かが足りないのですか?

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());

それは型安全性に違反するでしょう。

this基本的に、のインスタンスであるという保証はまったくありませんTItem。キャストがコンパイルされるのはそのためかもしれませんが、同様にそうではないかもしれません。そのキャストは本当に悪い考えです-それは型の安全性を実行時間に任せています、それはジェネリックの目的の反対です。

于 2012-10-01T17:49:29.430 に答える