4

C# のポリモーフィズムに問題があります。インターフェイスを実装するオブジェクトがありますが、オブジェクトのコレクションをインターフェイスのコレクションとして表現できません。これは、ポリモーフィズムに対する私の理解に反しています。だから私はどこが間違っているのだろうと思っていました。

[TestFixture]
class Tester
{
    [Test]
    public void Polymorphism()
    {
        var list = new List<Foo> {new Foo {Name = "Item"}};

        Assert.That(list, Is.InstanceOf<IList>());
        Assert.That(list[0], Is.InstanceOf<Foo>());
        Assert.That(list[0], Is.InstanceOf<IBar>());

        // why are the rest true but this false?
        Assert.That(list, Is.InstanceOf<IList<IBar>>());
    }
}

internal interface IBar
{
}

internal class Foo : IBar
{
    public string Name { get; set; }
}
4

3 に答える 3

4

これは分散の問題であり、ポリモーフィズムではありません。

List-of-Foo が IList-of-IBar でもある場合、次のように動作します。

class Another : IBar {}
IList<IBar> list = new List<Foo>();
list.Add(new Another());

次に、Another を Foo のリストに追加しました。これはエラーです。コンパイラは、あなたが間違いを犯すのを止めました。

最近のコンパイラ/.net バージョンは、"in"/"out" による差異をサポートしていることに注意してください。したがって、List-of-Foo は IEnumerable-of-IBar として問題ありません。これは Foo のみを返す(受け入れない)ことが保証されており、すべての Foo も IBar であるため、安全です。

于 2013-07-21T14:52:15.557 に答える
1

私も 2 セントを投入します。共分散と反分散の理解を深めると、発生している問題をよりよく理解できます ( http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faqを参照)。 .aspx )。

私はあなたのコードを少し修正し、この動作するテスト方法を思い付きました:

public void TestMethod1()
{
var list = new List<Foo> { new Foo { Name = "Item" } };
Assert.IsNotNull(list as IList);
Assert.IsNotNull(list[0] as Foo);
Assert.IsNotNull(list[0] as IBar);
Assert.IsNotNull(list as IList<Foo>);
Assert.IsNotNull((IList<Foo>)list);
}
于 2013-07-21T14:55:15.893 に答える