やあ、
自動フィクスチャを使用してDictionary<T, U>
を生成すると、デフォルトで値が入力されますが、 ConcurrentDictionary<T, U>
では入力されません。
これは仕様によるものであり、標本ビルダーを使用してその動作を自分で変更する必要がありますか、それとも欠落している機能またはバグですか?
他の誰かが同じ問題に遭遇した場合、私はこれのために標本ビルダーを書きました:
public class ConcurrentDictionaryGenerator : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
Type type = request as Type;
if (type == null)
{
return new NoSpecimen();
}
Type[] typeArguments = type.GetTypeInfo().GetGenericArguments();
if (typeArguments.Length != 2 || typeof(ConcurrentDictionary<,>).MakeGenericType(typeArguments) != type)
{
return new NoSpecimen();
}
Type nonConcurrentDictionaryType = typeof(Dictionary<,>).MakeGenericType(typeArguments);
IDictionary nonConcurrentDictionary = (IDictionary) context.Resolve(nonConcurrentDictionaryType);
IDictionary concurrentDictionary = (IDictionary) Activator.CreateInstance(type);
foreach (object key in nonConcurrentDictionary.Keys)
{
object value = nonConcurrentDictionary[key];
concurrentDictionary.Add(key, value);
}
return concurrentDictionary;
}
}
こんにちは、
この背後にある理由はわかりませんが、ソースコードを見ると、サポートされているコレクションはハードコーディングされています。
つまり、「タイプはIDictionaryを実装しますか」ではなく、「タイプDictionary <、>」です。 したがって、ConcurrentDictionaryは機能しません。
独自の標本ビルダーを作成する必要はありません。すでに存在するものを使用できます。
var fixture = new Fixture();
var query = new ModestConstructorQuery();
var methodInvoker = new MethodInvoker(query);
var dictionaryFiller = new DictionaryFiller();
var postProcessor = new Postprocessor(methodInvoker, dictionaryFiller);
var exactTypeSpecification = new ExactTypeSpecification(typeof(ConcurrentDictionary<,>));
var specimenBuilder = new FilteringSpecimenBuilder(postProcessor, exactTypeSpecification);
fixture.Customizations.Add(specimenBuilder);
このライブラリの内部について学ぶほど、私はそれを愛するようになります
それが現在Dictionary<,>
だけにあることを知るのは興味深いことであり、それを行うための組み込みの方法に感謝します!
誰かに残っている唯一の質問は、次のようになると思います。これは追加するのに適した機能でしょうか。 おそらくConcurrentDictionary<,>
の場合ではなく、すべてのIDictionary<,>
の実装ですか?
私が間違った情報を広めないというだけで、それは辞書<、>だけではありません。 タイプのリストはFixture.csに直接あります。 たとえば、SortedDictionary <、>でもありますが、すでに理解しているように、ConcurrentDictionary <、>ではありません。
どうしても、将来の実装ではインターフェースをチェックする必要があると思います。
実際には、ハードコーディングされているのはサポートではなく、インターフェイスが特定のタイプに中継されるという事実です。 IDictionaryやIReadOnlyDictionaryのように、Dictionaryなどに中継されます。
最も参考になるコメント
こんにちは、
この背後にある理由はわかりませんが、ソースコードを見ると、サポートされているコレクションはハードコーディングされています。
つまり、「タイプはIDictionaryを実装しますか」ではなく、「タイプDictionary <、>」です。 したがって、ConcurrentDictionaryは機能しません。
独自の標本ビルダーを作成する必要はありません。すでに存在するものを使用できます。