2015-07-14 2 views
1

Я пытаюсь написать простую строку перечисления. Очевидно, что я обычно использую стандартное перечисление, но мне нужны пробелы в строках.Альтернатива частным операторам неявного преобразования

Я попытался предотвратить строительство любых других экземпляров, сделав конструктор закрытым. Тем не менее, я также хотел неявное преобразование, чтобы сделать статические декларации проще/аккуратнее (последняя строка)

public class StringEnum 
{ 
    public static StringEnum Foo  = "A Foo"; 
    public static StringEnum Bar  = "A Bar"; 
    public static StringEnum Wibble = "A Wibble"; 
    public static StringEnum Crotchet = "A Crotchet"; 
    //etc... 

    //implicit cast to string 
    public static implicit operator string(StringEnum s) { return s.privateString; } 

    //private construction 
    private string privateString;  
    private StringEnum(string s) { this.privateString = s; } 
    private static implicit operator StringEnum(string s) { return new StringEnum(s); } 
} 

Этот неявный оператор не компилировать с «Модификатор частное не является допустимым для данного элемента». Я мог бы сделать его общедоступным, но тогда другой код может создавать не перечисляемые члены. Я мог бы просто избавиться и обновить статические экземпляры, но он выглядит намного опрятно, как указано выше.

Просто интересно, почему у вас не могут быть частные операторы конвертации, и может ли кто-нибудь предложить альтернативный способ, который удовлетворяет мой педантизм?

+3

Зачем вам нужны пробелы в именах? Не могли бы вы просто добавить атрибут отображаемого имени для каждого элемента в обычном перечислении? Или поиск для преобразования в строковое представление? – DavidG

+0

Вы ищете причину, отличную от того, что спецификация говорит: «Все операторы должны быть объявлены публичными и статическими». ? Как правило, они не поступают. –

ответ

2

Просто интересно, почему вы не можете иметь личное преобразование операторы

Операторы - это просто синтаксический сахар вокруг специальных методов. В случае неявного преобразования, оператор компилируются на что-то вроде:

public static string op_Implicit(StringEnum s) 
{ 
    // implementation 
} 

private методов предназначены, чтобы скрыть детали реализации - операторы предназначены, чтобы сделать код вне уборщика класса взгляда. В частном порядке было бы очень просто создать метод для преобразования, а не для неявного оператора. Поэтому очень важно иметь частный оператор, поскольку он влияет только на частный интерфейс - он вообще не влияет на публичный интерфейс. Таким образом, польза от такого признака не оправдывает затраты (проектирование, внедрение, тестирование, тестирование, и больше тестирования, документацию и техническое обслуживание)

и будет ли кто-то может предложить альтернативный путь, который удовлетворяет мой педантизм?

Просто сделайте «преобразование» частным методом вместо оператора.

2

От this answer:

Как почему разработчики языка решили требовать от операторов преобразования быть публичными ... Я предполагаю, что они, вероятно, хотели, чтобы избежать слишком много «магии» происходит с этими операторами-то нет, они не хотели, чтобы код функционировал в одном направлении внутри одной сборки и совершенно другим способом внутри другой сборки без каких-либо очевидных признаков того, что было .

Что касается альтернативного способа: вы можете просто пометить элементы перечислений с Description атрибутом и использовать отражение, чтобы получить «дружественное» имя участника:

public enum MyEnum 
{ 
    [Description("My Foo Member")] 
    FooMember, 
    Bar_Member 
} 

... 

public static string GetFriendlyName(Enum enumValue) 
{ 
    var descriptionAttribute = ReflectionUtil.GetAttribute<DescriptionAttribute>(enumValue); 
    return descriptionAttribute != null 
     ? descriptionAttribute.Description 
     : enumValue.ToString(); // or .Replace("_", " ") for example 
} 
+0

Большое спасибо за ваш ответ. К сожалению, я уже уволил атрибуты, так как они используют рефлексию, и IMO даже более беспорядочно, чем простой новый StringEnum(). Я пропустил другой вопрос, хотя так спасибо за ссылку. – GazTheDestroyer

+0

@GazTheDestroyer, пожалуйста. – andreycha

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