5

私はそれがかなり愚かであると信じています、そして私はこの種の質問をするのに少し恥ずかしいです、しかし私はまだ答えを見つけることができませんでした:

私は、実装するクラスを見ていList<T>ますIList

public class List<T> : IList

Ilistに含まれるメソッドの1つは

int Add(object value)

List<T>私はそれがその方法(型安全性...)を明らかにすべきではないことを理解しています、そしてそれは実際にはそうではありません。しかし、どうしてそれができるのでしょうか?mustntクラスはインターフェース全体を実装しますか?

4

6 に答える 6

10

この(インターフェース)メソッドは明示的に実装されていると思います:

public class List<T> : IList
{
     int IList.Add( object value ) {this.Add((T)value);}
}

そうすることで、Add( object )メソッドは非表示になります。List<T>インスタンスをインスタンスにキャストバックした場合にのみ、呼び出すことができIListます。

于 2010-12-08T14:50:28.867 に答える
3

リフレクターへのクイックトリップは、IList.Addが次のように実装されていることを示しています。

int IList.Add(object item)
{
    ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
    try
    {
        this.Add((T) item);
    }
    catch (InvalidCastException)
    {
        ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
    }
    return (this.Count - 1);
}

言い換えると、実装はそれをTにキャストして機能させ、 Tと互換性のないタイプを渡して失敗します。

于 2010-12-08T14:54:32.757 に答える
2

List<T>明示的に実装IList.Add(object value)するため、通常は表示されません。次の手順でテストできます。

IList list = new List<string>();
list.Add(new SqlDataReader()); // valid at compile time, will fail at runtime
于 2010-12-08T14:50:59.153 に答える
1

最初にリストインスタンスをインターフェイスにキャストしていると呼ぶことができます。

List<int> lst = new List<int>();
((IList)lst).Add("banana");

そして、あなたは素晴らしい、ランタイム、ArgumentExceptionを得るでしょう。

于 2010-12-08T14:53:20.507 に答える
1

フレデリクは、特定のメンバー、特に型安全性に脅威を与えるメンバーに対して、List<T>の実装が明示的であることは正しいです。IList

もちろん、彼が彼の答えで提案している実装は、コンパイルされないため、正しくありません。

このような場合、一般的なアプローチは、インターフェイスメンバーを機能させるために勇敢な努力をすることですが、それが不可能な場合は諦めます。

IList.Addメソッドは以下を返すように定義されていることに注意してください。

新しい要素が挿入された位置、またはアイテムがコレクションに挿入されなかったことを示す-1。

したがって、実際には、完全な実装可能です。

int IList.Add(object value)
{
    if (value is T)
    {
        Add((T)value);
        return Count - 1;
    }

    return -1;
}

もちろん、これは単なる推測です。(本当に知りたい場合は、いつでもReflectorを使用できます。)少し異なる場合があります。たとえば、をスローする可能性があります。これは、のNotSupportedException実装などの不完全なインターフェイス実装に対してよく行われます。しかし、上記はの文書化された要件を満たしているので、私はそれが本物に近いと思います。ReadOnlyCollection<T>IList<T>IList.Add

于 2010-12-08T14:54:39.990 に答える
1

IList明示的に実装されているため、使用するには最初にキャストする必要があります。

List<int> l = new List<int>();
IList il = (IList)l;
il.Add(something);
于 2010-12-08T14:51:38.573 に答える