2016-08-24 3 views
5

Я ищу, чтобы у вас возникли ошибки, чтобы предотвратить сборку, если в моем статическом словаре есть дубликаты ключей.Компилятор, чтобы проверить, являются ли ключи в словаре уникальными

Мой текущий словарь ниже

public static readonly Dictionary<string, string> Fruits = new Dictionary<string, string> 
{ 
    {"Sobeys", "Apples"}, 
    {"NoFrills", "Oranges"} 
} 

Но позволяет сказать, что кто-то случайно изменяет Sobeys быть NoFrills, я хотел бы ошибку компилятора быть поднят, чтобы предотвратить что-нибудь, чтобы быть сделано до тех пор, что ключ дубликатом не будет решена. Могу я спросить, возможно ли это? Если да, то как бы я мог это сделать?

public static readonly Dictionary<string, string> Fruits = new Dictionary<string, string> 
{ 
    {"NoFrills", "Apples"}, 
    {"NoFrills", "Oranges"} 
} 
+4

Вы должны написать свой собственный компилятор, если вы хотите иметь различное поведение, чем правила C#. – Servy

+3

Вы используете Visual Studio 2015 или новее? Если это возможно, с помощью специального [анализатора кода в реальном времени] (https://msdn.microsoft.com/en-us/magazine/dn879356.aspx), но это будет непростое количество работы, чтобы сделать это надежный. –

+0

@Servy Поскольку C# является открытым исходным кодом, возможно, вместо этого патч должен быть отправлен сообществу. https://github.com/dotnet/roslyn –

ответ

6

Вы также можете использовать следующий хак (я не рекомендую): конвертировать анонимный тип в словарь. Анонимные типы не позволяют дублировать имена свойств.

Пример:

Dictionary<string, string> Fruits = ToDictionary(
    new 
    { 
     Sobeys = "Apples", 
     NoFrills = "Oranges" 
    } 
); 

Но этот подход имеет следующие ограничения: вы можете иметь только действительные идентификаторы в качестве ключей в словаре.

Как реализовать ToDictionary метод описан здесь: In c# convert anonymous type into key/value array?

+0

Интересно, я дам это быстро! – Master

+2

Это очень умная идея. – sstan

+0

Привет, определенно взломать, но это по сути то, что я хотел. Спасибо @ just.ru – Master

8

Нет, это время от времени. Как только класс загружается в память, он будет генерировать исключение (которое по своей сути является временем выполнения).

Вы можете добавить пользовательскую проверку через диагностический анализатор, но это будет очень больно для получения очень небольшого выигрыша. Я предлагаю вам просто оставить его таким, как есть, и следить за любыми исключениями при новом развертывании. Вы всегда можете добавить комментарий, чтобы дать понять другим разработчикам, что ключи должны быть уникальными, но где вы остановились? Предполагается, что разработчик должен знать основные правила фреймворка.

Вы также можете использовать, например, перечисление в качестве ключа, которое позволит очистить его в devtime, когда вы попытаетесь добавить что-то, что уже существует. Другой вариант - обратиться к полям const string, хотя он остается несколько хрупким.

+1

Я бы очень хотел сказать то же самое, что и вы, но единственное, что я бы добавил к этому, это хорошая работа для тестирования модулей, чтобы поймать –

+0

@ScottChamberlain Unit Tests поможет, если добавление было выполнено с помощью метода, но вы не можете выполнить единичный тест, если он уже дублируется при инициализации курса –

+0

@JeroenVannevel? Доступ к этому свойству завершится с ошибкой, поэтому тест с его использованием не удастся ... Не знаете, почему вы должны писать тест, который преуспевает, когда возникает исключение ... –

1

Компилятор C# не предоставляет такую ​​возможность. Вы получите исключение во время выполнения.

Чтобы решить эту проблему, вам необходимо выполнить собственные проверки предварительной обработки или обработать исключения времени выполнения.

1

Я хотел бы ошибку компилятора поднять

Это не ошибка. Вот почему компилятор не выпускает ошибку времени компиляции. Инициализатор коллекции - это синтаксический сахар и переводятся в соответствующий метод Add() (или указатель в случае альтернативного синтаксиса).

Ваш лучший вариант - положиться на какой-то сторонний инструмент анализа кода, который может обнаружить такие ошибки .

Смежные вопросы