12

私はこのようなことをしたいです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test
{
    public interface IFoo
    {
        IEnumerable<int> integers { get; set; }
    }

    public class Bar : IFoo
    {
        public List<int> integers { get; set; }
    }
}

なぜコンパイラが文句を言うのですか..?

Error   2   'Test.Bar' does not implement interface member 'Test.IFoo.integers'. 'Test.Bar.integers' cannot implement 'Test.IFoo.integers' because it does not have the matching return type of 'System.Collections.Generic.IEnumerable<int>'.

インターフェイスがIEnumerableと表示され、クラスがリストを使用していることを理解していますが、リストIEnumerableです....。

私に何ができる?クラスでIEnumerableを指定したくないので、List...のようにIEnumerableを実装する具象型を使用したい。

4

3 に答える 3

12

これはタイプ共変性/反変性の問題です(http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#C.23を参照)。

回避策があります。次のような明示的なインターフェイスを使用します。

public class Bar : IFoo {

    private IList<int> _integers;

    IEnumerable<int> IFoo.integers {
        get { return _integers };
        set { _integers = value as IList<int>; }
    }

    public IList<int> integers {
        get { return _integers; }
        set { _integers = vale; }
    }
}

integers.NETのガイドラインに準拠するには、TitleCasedである必要があることに注意してください。

うまくいけば、上記のコードで問題を確認できます。アクセサとのみIList<int>互換性があり、設定とは互換性がありません。IEnumerable<int>誰かが電話をかけた場合はどうなりますIFoo.integers = new Qux<int>()(どこQux : IEnumerable<int>でも)。 Qux : IList<int>

于 2013-03-19T02:45:24.193 に答える
5

ListはIEnumerableを実装していますが、これはインターフェイスの動作方法ではありません。インターフェイスは、プロパティに対して公開する必要のあるタイプを正確に指定します。次のような汎用インターフェースを作成した場合

public interface IFoo<T> where T : IEnumerable<int>
{
    T integers { get; set; }
}

IFoo<List<int>>その後、期待どおりに実装するために使用できます。

于 2013-03-19T02:46:37.297 に答える
3

舞台裏でやらないと具体的なタイプは使えません。問題は、プロパティの取得と設定の両方ができることです。

インターフェイスは、プロパティがタイプであることを指定していますIEnumerable<int>HashSet<int>を実装しIEnumerable<int>ます。つまり、以下は問題なく機能するはずです。

IFoo instance = new Bar();
instance.integers = new HashSet<int>();

ただし、具象型を使用してインターフェースを実装しようとしているためList<int>、割り当てが機能する方法はありません。

コレクションを常に再割り当てする必要がないと仮定した場合の最も簡単な修正は、コレクションのゲッターのみを指定することです。

public interface IFoo
{
    IEnumerable<int> Integers { get; }
}

public class Bar
{
    public List<int> Integers { get; private set; }

    public Bar(List<int> list)
    {
        Integers = list;
    }
}
于 2013-03-19T02:47:28.080 に答える