使用其他 class 常量值调用构造函数
Call constructor with other class constant value
我希望构造函数调用只允许有限范围的 "extensions"。假设我有这 2 classes:
public class Foo
{
public Foo(Extension ext)
{
// do something
}
}
public class Extension
{
public const string TXT = ".txt";
public const string XML = ".xml";
}
因此,当另一个开发人员想要使用 Foo
时,他只能使用 Extension
class 中的值,如下所示:
Foo foo = new Foo(Extension.TXT);
但是当尝试这样做时,我收到一个 IDE 错误消息:"cannot convert from 'string' to '<ProjectName>.Extension'
.
作为一个 "workaround" 我可以将我的 Extension
class 改成这样:
public class Extension
{
public enum File
{
TXT,
XML
}
}
并像这样使用它:
Foo foo = new Foo(Extension.File.TXT);
效果很好,但我不喜欢的是调用时间长了一级(class -> enum -> element 而不是 class -> element)。
所以,问题是我的解决方法实际上是唯一有效、正确或最佳实践的解决方案吗?
第一个示例将 Extension
用作带有几个字符串常量的 class。第二个示例使用枚举代替常量。
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 可用的值,因此请使用第二个示例中的枚举:
public class Foo
{
public Foo(File ext)
{
// do something
}
}
public enum File
{
TXT,
XML
}
然后这将按预期工作:
Foo foo = new Foo(File.TXT);
您可以为扩展字符串定义默认构造函数和隐式运算符。例如。类似于:
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;}
}
您可以使用 Java 样式枚举 class
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();
}
}
为什么不在 class Foo 之外声明枚举并且没有任何特殊的 class 扩展名?
public enum Extension
{
TXT,
XML
}
public class Foo
{
public Foo(Extension ext)
{
// do something
}
}
然后当你构造一个 Foo 对象时,你可以简单地做:
Foo foo = new Foo(Extension.TXT);
只需将Extension的第一个声明从Class更改为Enum
我希望构造函数调用只允许有限范围的 "extensions"。假设我有这 2 classes:
public class Foo
{
public Foo(Extension ext)
{
// do something
}
}
public class Extension
{
public const string TXT = ".txt";
public const string XML = ".xml";
}
因此,当另一个开发人员想要使用 Foo
时,他只能使用 Extension
class 中的值,如下所示:
Foo foo = new Foo(Extension.TXT);
但是当尝试这样做时,我收到一个 IDE 错误消息:"cannot convert from 'string' to '<ProjectName>.Extension'
.
作为一个 "workaround" 我可以将我的 Extension
class 改成这样:
public class Extension
{
public enum File
{
TXT,
XML
}
}
并像这样使用它:
Foo foo = new Foo(Extension.File.TXT);
效果很好,但我不喜欢的是调用时间长了一级(class -> enum -> element 而不是 class -> element)。
所以,问题是我的解决方法实际上是唯一有效、正确或最佳实践的解决方案吗?
第一个示例将 Extension
用作带有几个字符串常量的 class。第二个示例使用枚举代替常量。
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 可用的值,因此请使用第二个示例中的枚举:
public class Foo
{
public Foo(File ext)
{
// do something
}
}
public enum File
{
TXT,
XML
}
然后这将按预期工作:
Foo foo = new Foo(File.TXT);
您可以为扩展字符串定义默认构造函数和隐式运算符。例如。类似于:
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;}
}
您可以使用 Java 样式枚举 class
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();
}
}
为什么不在 class Foo 之外声明枚举并且没有任何特殊的 class 扩展名?
public enum Extension
{
TXT,
XML
}
public class Foo
{
public Foo(Extension ext)
{
// do something
}
}
然后当你构造一个 Foo 对象时,你可以简单地做:
Foo foo = new Foo(Extension.TXT);
只需将Extension的第一个声明从Class更改为Enum