0

私はこのようなクラス階層を持っています

public class A
{
    protected class B 
    {
        String Name { get; set; }
    }

    protected class C : KeyedCollection<String, B> 
    {
        // ...
    }

    protected C Collection { get; }

    // ...

    public A Copy () 
    {
        // Creates a deep copy of this instance.
    }
}

ここで、A の 2 つのインスタンスがプロパティ KeyedCollection 内に同じ項目 B を持っているかどうかを比較する単体テストを作成したいと思います。ただし、A インスタンスに対して foreach ループを実行できません。私が試したこと、

[TestClass]
public class TestClass
{
    public void ATest()
    {
        A original = new A();
        A copy = A.Copy();

        // ...

        A_Accessor originalAccessor = A_Accessor.AttachShadow(original);
        A_Accessor copyAccessor = A_Accessor.AttachShadow(copy);

        foreach(var originalItem in originalAccessor.Collection)
        {
            var copyItem = copyAccessor[originalItem.Name];
            Assert.AreEqual(originalItem, copyItem);
        }
    }
}

このコードは、C クラス アクセサーが IEnumerable インターフェイスを実装していない (KeyedCollection クラスからのインターフェイスを実装していない) ため、コンパイルされません。この問題をどのように克服できるかについて、誰かが考えを持っていますか?

私が得ているエラーメッセージは

'A_Accessor.C' には 'GetEnumerator' のパブリック定義が含まれていないため、foreach ステートメントはタイプ 'C' の変数を操作できません

4

4 に答える 4

0

実際、私が見つけた解決策は、Martin の提案と非常によく似ていました。

var originalItems = 
    from item in (originalAccessor.Collection.Target as IEnumerable).Cast<Object>()
    select A_Accessor.B.AttachShadow(item);

var copyItems = 
    from item in (copyAccessor.Collection.Target as IEnumerable).Cast<Object>()
    select A_Accessor.B.AttachShadow(item); 

foreach(var original in originalItems) 
{ 
    String originalName = original.Name;
    A_Accessor.B copy = copyItems.First(b => b.Name == originalName);

    // ...
}

ご協力ありがとうございました!カルロス。

于 2010-02-01T18:53:00.060 に答える
0

あなたの例をコンパイルしようとしました: 予想どおり、エラーが発生しました

Inconsistent accessibility: field type 'A.C' is less accessible than field 'A.Collection'.

つまり、プライベート タイプを使用して保護されたプロパティを宣言することはできません。したがって、テストコードの問題ではなく、テストするコードの問題です...

編集

originalAccessor.Collection.Targetにキャストして使用できますICollection。もちろんobject、この場合は s しか列挙できないため、各アイテムを再度キャストする必要があります。

foreach (var item in (originalAccessor.Collection.Target as ICollection)) {
   A_Accessor.B casted = A_Accessor.B.AttachShadow(item);
   var copyItem = copyAccessor[casted.Name];
   Assert.AreEqual(casted, copyItem);
}
于 2010-02-01T17:53:03.503 に答える
0

ライブラリのユーザー向けに意図された API レベルではなく、実装の詳細をテストしているように思えます。

于 2010-02-02T10:52:03.320 に答える
0

最初に保護されたプロパティを介してプライベート クラス タイプを公開する方法は明確ではありませんが、C が派生 KeyedCollectionするため、既に の実装を継承する必要がありIEnumerable<B>ます。

何をしようとしているのかは明確ではありませんが、コレクションを反復処理できるはずです...プロパティを見ることさえできれば。あなたのコードは他の理由でコンパイルされていないと思われます-C保護されているにもかかわらず、プライベートメンバー型に関して宣言されているため、およびC最初に別のクラスからアクセスしようとしているためです(保護されているにもかかわらず)。

于 2010-02-01T17:42:40.623 に答える