2016-07-27 4 views
0

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

public class Foo 
{ 
    public Foo(Extension ext) 
    { 
     // do something 
    } 
} 

public class Extension 
{ 
    public const string TXT = ".txt"; 
    public const string XML = ".xml"; 
} 

Так что, когда другой разработчик захочет использовать Foo он может сделать это только со значениями из Extension класса как так:

Foo foo = new Foo(Extension.TXT); 

Но при попытке для этого я получаю ошибку IDE, говорящую: "cannot convert from 'string' to '<ProjectName>.Extension'.

В качестве «обходного» Я мог бы изменить свой Extension класс что-то вроде этого:

public class Extension 
{ 
    public enum File 
    { 
     TXT, 
     XML 
    } 
} 

и использовать его как это:

Foo foo = new Foo(Extension.File.TXT); 

, который отлично работает, но то, что мне не нравится заключается в том, что вызов на один уровень длиннее (класс -> элемент enum -> вместо класса ->).

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

+3

Удалите Num из класса и сделать его общественности. Вы будете вызывать только перечисление: 'new Foo (File.Txt);'. –

ответ

5

Вы можете использовать Java стиль перечислимую класс

public class Extension 
{ 
    string _Extension = null; 

    private Extension(string ext) 
    { 
     _Extension = ext; 
    } 

    public static Extension TXT 
    { 
     get { return new Extension(".txt"); } 
    } 

    public static Extension XML 
    { 
     get { return new Extension(".xml"); } 
    } 

    public override string ToString() 
    { 
     return _Extension; 
    } 

    public override bool Equals(object obj) 
    { 
     var e = obj as Extension; 
     if (e == null) return false; 

     return e._Extension == this._Extension; 
    } 

    public override int GetHashCode() 
    { 
     return _Extension.GetHashCode(); 
    } 
} 
3

Первый пример: Extension используется как класс с несколькими строковыми константами. Второй пример использует перечисление вместо констант.

public class Foo 
{ 
    // this .ctor expects a type of Extension, not a string. 
    public Foo(Extension ext) 
    { 
     // do something 
    } 
} 

// This class has only constant string values. 
public class Extension 
{ 
    public const string TXT = ".txt"; 
    public const string XML = ".xml"; 
} 

Попытка передать строку в выше .ctor не будет работать, как он ожидает, тип Extension, а не строка.

// this passes in a string, not a type. 
Foo foo = new Foo(Extension.TXT); 

Как вы желаете, чтобы ограничить значения, доступные для Foo .ctor, а затем использовать перечисление, как у вас в 2 Например:

public class Foo 
{ 
    public Foo(File ext) 
    { 
     // do something 
    } 
} 

public enum File 
{ 
    TXT, 
    XML 
} 

Тогда это будет работать, как ожидалось:

Foo foo = new Foo(File.TXT); 
0

Вы можете определить конструктор по умолчанию и неявный оператор для строки в Extension. Например. что-то вроде:

public class Extension 
{ 
    public const string TXT = ".txt"; 
    public const string XML = ".xml"; 

    private _value; 
    public Extension(string value){if(value == TXT || value == XML) _value = value; else throw new NotImplementedException();} 
    public static implicit operator string(Extension value){return _value;} 
    public static implicit operator Extension(string value){if(value == TXT || value == XML) _value = value; else throw new NotImplementedException();} 
} 

что, как вы могли бы назвать Foo (".txt".) или Foo (Extension.TXT)

или вы могли бы определить TXT как пример расширения:

public class Extension 
{ 
    public const Extension TXT = new Extension(".txt"); 
    public const Extension XML = new Extension(".xml"); 

    public Value{get;private set;} 
    public Extension(string value){Value = value;} 
} 
1

Почему бы не отменить clare enum вне класса Foo и без какого-либо специального класса, такого как расширение?

public enum Extension 
{ 
    TXT, 
    XML 
} 

public class Foo 
{ 
    public Foo(Extension ext) 
    { 
     // do something 
    } 
} 

Затем, когда вы строите Foo объект, который вы можете просто сделать:

Foo foo = new Foo(Extension.TXT); 
0

Просто измените первую декларацию Extesion от класса к ENUM

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