我想定义一个具有有限元素集的值类型,这些元素又是运行时动态定义列表的元素(例如来自数据库).
有了这个,我希望能够在动态列表上强制执行类型安全(好吧,排序)而不需要在编译时提供任何值.然后,我可以在我的代码中使用新类型作为属性,作为方法中的返回值等.
(注意 - 它不是真正的类型 - "安全",即我追求的编译时检查,而是在方法和属性中概念性地识别"这种类型的值"的能力 - 为了更好的可理解性和代码的可读性. )
伪代码:
type Currency = ["USD", "EUR", "GBP"];
Currency cur = new Currency();
cur = "CAD"; // must throw an exception
Currency.Add("CAD");
cur = "CAD"; // now it would NOT throw an exception
Run Code Online (Sandbox Code Playgroud)
它有点像"String"的子类,但String是一个密封类,不能派生自.
您还可以将其视为定义为从列表中返回"ValueOf"函数的类型.但这并没有给我一种在C#中定义类型的方法.
有没有合理明智的方法来做我想要的事情?
请注意,当您谈论Type Safety时,大多数C#开发人员会自动假设您正在讨论编译时检查.由于这不是你所要求的,有些人会被推迟.
你要求做的不是真正的语言功能,而是你可以用简单的编程概念做的事情:
void Main()
{
Currency.Add("USD", "EUR", "GBP");
Currency cur = new Currency("CAD"); // must throw an exception
Currency.Add("CAD");
cur = new Currency("CAD"); // now it would NOT throw an exception
}
public class Currency{
private static List<string> availableValues = new List<string>();
public static void Add(params string[] values){
foreach (var value in values)
{
availableValues.Add(value);
}
}
public Currency(string value){
if(!availableValues.Contains(value)){
throw new ArgumentOutOfRangeException(nameof(value), value + " is not a valid Currency");
}
this.Value = value;
}
public string Value{get;}
public override string ToString() => Value;
}
Run Code Online (Sandbox Code Playgroud)
此代码假定您将在启动时注册所有可用货币.如果您希望在积极使用类时添加新值,则需要使用类似a ConcurrentDictionary<>而不是a的内容List<>.
并且可以创建隐式转换运算符以使Currency cur = "CAD";语法有效.您还可以创建另一个转换运算符,以便将Currency自动转换为String(而不是需要访问Value属性).
public static implicit operator Currency(string name) =>
new Currency(name);
public static implicit operator string(Currency currency) =>
currency.Value;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
52 次 |
| 最近记录: |