Привет,
Когда я использую autofixture для создания 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<,>
?
Просто я не распространяю неверную информацию, это не только Dictionary<,>. Я просто хотел отметить, что список типов можно найти непосредственно в Fixture.cs. Например, это также SortedDictionary<,>, но, как вы уже поняли, это не ConcurrentDictionary<,>.
Во что бы то ни стало, я бы сказал, что будущая реализация должна проверять интерфейс.
На самом деле то, что жестко запрограммировано, это не поддержка, а тот факт, что интерфейсы ретранслируются на какой-то конкретный тип. Например, IDictionary и IReadOnlyDictionary ретранслируются в Dictionary и так далее.
Самый полезный комментарий
Привет,
Я не могу назвать причины этого, но, глядя на исходный код, поддерживаемые коллекции жестко закодированы.
Так что это не что-то вроде «реализует ли тип IDictionary», это «это тип Dictionary<,>». Поэтому ConcurrentDictionary не работает.
Вам не нужно создавать свой собственный конструктор образцов, вы можете использовать то, что уже есть: