2016-07-27 39 views
0

Ich möchte einen Konstruktor Aufruf nur eine begrenzte Anzahl von "Erweiterungen" zulassen. Lassen Sie uns sagen, ich habe diese 2 Klassen:Aufruf Konstruktor mit anderen Klassenkonstanten Wert

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

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

Also, wenn ein anderer Entwickler Foo verwenden möchte, kann er dies nur tun, mit den Werten aus der Extension Klasse wie folgt:

Foo foo = new Foo(Extension.TXT); 

Aber wenn man versucht, um dies zu tun, bekomme ich einen IDE-Fehler, der sagt: "cannot convert from 'string' to '<ProjectName>.Extension'.

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

und es wie folgt verwenden:

Als „Abhilfe“ Ich konnte meine Extension Klasse so etwas wie dies ändern

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

, die perfekt funktioniert gut, aber was Ich mag es nicht ist, dass der Aufruf eine Ebene länger ist (Klasse -> Enum -> Element statt Klasse -> Element).

Also ist die Frage, ist meine Problemumgehung eigentlich die einzige gültige, korrekte oder Best-Practice-Lösung?

+3

entfernen und es machen Öffentlichkeit. Sie rufen nur die enum auf: 'new Foo (File.Txt);'. –

Antwort

5

Sie einen Java Stil enum können Klasse

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

Das erste Beispiel hat Extension wird als eine Klasse mit ein paar String-Konstanten verwendet. Das zweite Beispiel verwendet eine Aufzählung anstelle der Konstanten.

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"; 
} 

Der Versuch, in einer Zeichenfolge zu dem oben .ctor funktionieren nicht passieren, da es eine Art von Extension erwartet, kein String.

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

Wie Sie wollen, sind die Werte in den Foo .ctor zur Verfügung zu begrenzen, dann eine ENUM nutzen, wie Sie in Ihrem zweiten Beispiel haben:

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

public enum File 
{ 
    TXT, 
    XML 
} 

Dann wird diese wie erwartet:

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

Sie könnten einen Standardkonstruktor und einen impliziten Operator für die Zeichenfolge Extension definieren. Z.B. so etwas wie:

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();} 
} 

auf diese Weise Sie Foo nennen könnte ("txt".) oder Foo (Extension.TXT)

oder Sie könnten TXT definieren als eine Instanz der Erweiterung:

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

Warum nicht de clare enum außerhalb der Klasse Foo und ohne besondere Klasse wie Erweiterung?

public enum Extension 
{ 
    TXT, 
    XML 
} 

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

Dann, wenn Sie ein Foo konstruieren Objekt, das Sie einfach tun:

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

einfach die erste Erklärung von Extesion aus der Klasse ändern Sie die num aus der Klasse ENUM