动态ValueOfType强制实施

时间:2018-09-27 15:04:51

标签: c#

我想定义一个具有有限元素集的值类型,这些元素又是运行时动态定义的列表的元素(例如,来自数据库)。

有了这个,我希望能够在动态列表上强制类型安全(很好,有点),而在编译时没有任何可用的值。然后,我可以在代码中将新类型用作属性,作为方法等中的返回值。

(注意-这并不是真正的“安全”类型,即我所追求的编译时检查,而是能够在概念上识别方法和属性中“这种类型的值”的能力-以便更好地理解和理解代码。)

伪代码:

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

它有点像“ String”的子类,但是String是密封的类,不能从中派生。

您还可以将其视为定义为从列表中返回“ ValueOf”函数的类型。但这并没有给我提供在C#中定义类型的方法。

有什么合理的方法可以做我想要的吗?

1 个答案:

答案 0 :(得分:5)

请注意,当您谈论类型安全时,大多数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;
}

此代码假定您将在启动时注册所有可用货币。如果您希望在积极使用该类的同时添加新的值,则可以使用ConcurrentDictionary<>之类的东西来代替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;