C#中带有泛型和动态关键字的动态配置文件

时间:2015-03-19 13:50:34

标签: c# generics dynamic

我的目标是创建一个可以存储和保存强类型值的Configuration类。我采取的方法如下。我的整个设计可能存在缺陷,但这是我第三次从头开始重写,而且我不确定如何解决这个问题。我在尝试实现动态方法来获取值时遇到了麻烦。

具体来说,我想知道如何存储Type并稍后将其用作Type Parameter ...但我也对一般的设计建议持开放态度。

我已经在这里复制了我的全部代码。

public class ConfigExample
{
    private HashSet<ConfigEntry> _entries;
    private Dictionary<string, Type> _entryTypes; 

    public ConfigExample()
    {
        _entries = new HashSet<ConfigEntry>();
    }

    public dynamic this[string propName]
    {
        get
        {
            var e = _entries.FirstOrDefault(p => p.PropertyName == propName);
            var t = _entryTypes[propName];
            var cast = e as ConfigEntry<t>;
            if (cast != null)
                return cast.Value;
        }
        set
        {

        }
    }

    public dynamic Get(string propName)
    {
        var e = _entries.FirstOrDefault(p => p.PropertyName == propName);
        if (e == null)
            throw new ArgumentException("Property name does not exist.");

        var castBool = e as ConfigEntry<bool>;
        if (castBool != null)
            return castBool.Value;

        var castInt = e as ConfigEntry<int>;
        if (castInt != null)
            return castInt.Value;

        var castString = e as ConfigEntry<string>;
        if (castString != null)
            return castString.Value;

        throw new InvalidOperationException("Could not cast value");
    }

    public T Get<T>(string propName)
    {
        var e = _entries.FirstOrDefault(p => p.PropertyName == propName);
        if (e == null)
            throw new ArgumentException("Property name does not exist.");

        var cast = e as ConfigEntry<T>;
        if (cast == null)
            throw new ArgumentException("Property is not of given type");

        return cast.Value;
    }

    public void Set<T>(string propName, T val)
    {
        var e = _entries.FirstOrDefault(p => p.PropertyName == propName);
        if (e == null)
            throw new ArgumentException("Property does not exist.");

        var cast = e as ConfigEntry<T>;
        if (cast == null)
            throw new ArgumentException("Property is not of given type.");

        cast.Value = val;
    }
}

internal abstract class ConfigEntry
{
    protected ConfigEntry(string propName)
    {
        PropertyName = propName;
    }

    public string PropertyName { get; set; }
}

internal class ConfigEntry<T> : ConfigEntry
{
    public ConfigEntry(string propName, T val) : base(propName)
    {
        Value = val;
    }

    public T Value { get; set; }
}

0 个答案:

没有答案