Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 名称空间dict?_C# - Fatal编程技术网

C# 名称空间dict?

C# 名称空间dict?,c#,C#,我正在设计一种模板语言。其中有3种标记:标记、指令和变量。这些代币中的每一个都有一个名字,而且会有相当多的代币。它们也是可扩展的 为了允许名称重用,我想添加名称空间 现在所有变量都存储在一个dict中。键是变量名,值是变量值。这样我可以快速检索变量的值。但是,假设我想允许点表示法,namespace.variable,我如何存储这些变量,以便名称空间是可选的?如果包含名称空间,dict应该只扫描该名称空间,如果没有,我想它会扫描所有名称空间 是否有一个容器可以做到这一点?您应该在内部将符号数据构

我正在设计一种模板语言。其中有3种标记:标记、指令和变量。这些代币中的每一个都有一个名字,而且会有相当多的代币。它们也是可扩展的

为了允许名称重用,我想添加名称空间

现在所有变量都存储在一个dict中。键是变量名,值是变量值。这样我可以快速检索变量的值。但是,假设我想允许点表示法,
namespace.variable
,我如何存储这些变量,以便名称空间是可选的?如果包含名称空间,dict应该只扫描该名称空间,如果没有,我想它会扫描所有名称空间


是否有一个容器可以做到这一点?

您应该在内部将符号数据构造为字符串字典。顶级字典用于名称空间,每个名称空间名称下的每个字典都是该名称空间中所有符号的容器


查找非限定符号只是在每个名称空间中按特定顺序查找符号。在C#或Delphi中,名称空间在源文件顶部声明的顺序与声明的顺序相反(最新的是第一个被搜索的名称空间)。

您可以创建自己的
IDictionary
实现,而不必使用框架的
字典

从外部来看,你的消费方式不会改变

在内部,它将由一个
字典
组成

因此,如果您的字典需要与键
“namespace.variable”
匹配的值,它会在内部拆分该字符串,获取带有键“namespace”的
字典
,然后返回该
字典中键“variable”的值

要使名称空间成为可选的,您有一个项,其中键为
string.Empty
。无论是添加项还是获取项,只要提供了不包含
的项,您都将使用带有key
字符串的项。空的

我的解决方案:

等级
公共类名称空间字典:IDictionary
{
私人分类词典;
私有常量字符_分隔符=';
公共名称空间字典()
{
_dict=新的SortedDictionary();
}
公共名称空间字典(IEnumerable集合)
:此()
{
foreach(集合中的var项)
增加(项目);
}
#IEnumerable的区域实现
公共IEnumerator GetEnumerator()
{
return _dict.SelectMany(x=>x.Value).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
#端区
私有静态元组拆分(字符串名称)
{
int pos=name.LastIndexOf(_分隔符);
字符串ns=pos==-1?“:name.Substring(0,pos);
字符串var=name.Substring(位置+1);
返回新元组(ns,var);
}
#ICollection的区域实现
公共作废添加(KeyValuePair项)
{
添加(item.Key、item.Value);
}
公共空间清除()
{
_格言(Clear);
}
public bool包含(KeyValuePair项)
{
抛出新的NotImplementedException();
}
public void CopyTo(KeyValuePair[]数组,int-arrayIndex)
{
抛出新的NotImplementedException();
}
公共布尔删除(KeyValuePair项)
{
返回删除(项.Key);
}
公共整数计数
{
获取{return _dict.Sum(p=>p.Value.Count);}
}
公共图书馆是只读的
{
获取{return false;}
}
#端区
#IDictionary的区域实现
公共bool ContainsKey(字符串名称)
{
变量tuple=Split(名称);
返回ContainsKey(tuple.Item1,tuple.Item2);
}
公共bool ContainsKey(字符串ns、字符串键)
{
如果(ns==“”)
返回_dict.Any(pair=>pair.Value.ContainsKey(key));
返回_dict.ContainsKey(ns)和&_dict[ns].ContainsKey(key);
}
公共void Add(字符串名称,T值)
{
变量tuple=Split(名称);
添加(tuple.Item1、tuple.Item2、value);
}
公共无效添加(字符串ns、字符串键、T值)
{
如果(!_dict.ContainsKey(ns))
_dict[ns]=新字典();
_dict[ns]。添加(键,值);
}
公共布尔删除(字符串ns、字符串键)
{
if(_dict.ContainsKey(ns)&&&&(u dict[ns].ContainsKey(key))
{
如果(_dict[ns].Count==1)_dict.Remove(ns);
else _dict[ns]。删除(键);
返回true;
}
返回false;
}
公共布尔删除(字符串键)
{
变量元组=拆分(键);
返回Remove(tuple.Item1,tuple.Item2);
}
public bool TryGetValue(字符串名称,out T值)
{
变量tuple=Split(名称);
返回TryGetValue(tuple.Item1、tuple.Item2、out值);
}
公共bool TryGetValue(字符串ns、字符串键、输出T值)
{
如果(ns==“”)
{
foreach(变量对在dict中)
{
if(pair.Value.ContainsKey(key))
{
value=pair.value[key];
返回true;
}
}
}
else if(_dict.ContainsKey(ns)和&&&u dict[ns].ContainsKey(key))
{
值=_dict[ns][key];
返回true;
}
值=默认值(T);
返回false;
}
公共T此[string ns,string key]
{
得到
{
如果(ns==“”)
{
foreach(变量对在dict中)
if(pair.Value.ContainsKey(key))
返回pair.Value[key];
}
else if(_dict.ContainsKey(ns)和&&&u dict[ns].ContainsKey(key))
返回_dict[ns][key];
抛出新的KeyNotFoundException();
}
设置
public class NamespaceDictionary<T> : IDictionary<string, T>
{
    private SortedDictionary<string, Dictionary<string, T>> _dict;
    private const char _separator = '.';

    public NamespaceDictionary()
    {
        _dict = new SortedDictionary<string, Dictionary<string, T>>();
    }

    public NamespaceDictionary(IEnumerable<KeyValuePair<string, T>> collection)
        : this()
    {
        foreach (var item in collection)
            Add(item);
    }

    #region Implementation of IEnumerable

    public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
    {
        return _dict.SelectMany(x => x.Value).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion

    private static Tuple<string, string> Split(string name)
    {
        int pos = name.LastIndexOf(_separator);
        string ns = pos == -1 ? "" : name.Substring(0, pos);
        string var = name.Substring(pos + 1);
        return new Tuple<string, string>(ns, var);
    }

    #region Implementation of ICollection<KeyValuePair<string,TValue>>

    public void Add(KeyValuePair<string, T> item)
    {
        Add(item.Key, item.Value);
    }

    public void Clear()
    {
        _dict.Clear();
    }

    public bool Contains(KeyValuePair<string, T> item)
    {
        throw new NotImplementedException();
    }

    public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
    {
        throw new NotImplementedException();
    }

    public bool Remove(KeyValuePair<string, T> item)
    {
        return Remove(item.Key);
    }

    public int Count
    {
        get { return _dict.Sum(p => p.Value.Count); }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    #endregion

    #region Implementation of IDictionary<string,TValue>

    public bool ContainsKey(string name)
    {
        var tuple = Split(name);
        return ContainsKey(tuple.Item1, tuple.Item2);
    }

    public bool ContainsKey(string ns, string key)
    {
        if (ns == "")
            return _dict.Any(pair => pair.Value.ContainsKey(key));
        return _dict.ContainsKey(ns) && _dict[ns].ContainsKey(key);
    }

    public void Add(string name, T value)
    {
        var tuple = Split(name);
        Add(tuple.Item1, tuple.Item2, value);
    }

    public void Add(string ns, string key, T value)
    {
        if (!_dict.ContainsKey(ns))
            _dict[ns] = new Dictionary<string, T>();
        _dict[ns].Add(key, value);
    }

    public bool Remove(string ns, string key)
    {
        if (_dict.ContainsKey(ns) && _dict[ns].ContainsKey(key))
        {
            if (_dict[ns].Count == 1) _dict.Remove(ns);
            else _dict[ns].Remove(key);
            return true;
        }
        return false;
    }

    public bool Remove(string key)
    {
        var tuple = Split(key);
        return Remove(tuple.Item1, tuple.Item2);
    }

    public bool TryGetValue(string name, out T value)
    {
        var tuple = Split(name);
        return TryGetValue(tuple.Item1, tuple.Item2, out value);
    }

    public bool TryGetValue(string ns, string key, out T value)
    {
        if (ns == "")
        {
            foreach (var pair in _dict)
            {
                if (pair.Value.ContainsKey(key))
                {
                    value = pair.Value[key];
                    return true;
                }
            }
        }
        else if (_dict.ContainsKey(ns) && _dict[ns].ContainsKey(key))
        {
            value = _dict[ns][key];
            return true;
        }
        value = default(T);
        return false;
    }

    public T this[string ns, string key]
    {
        get
        {
            if (ns == "")
            {
                foreach (var pair in _dict)
                    if (pair.Value.ContainsKey(key))
                        return pair.Value[key];
            }
            else if (_dict.ContainsKey(ns) && _dict[ns].ContainsKey(key))
                return _dict[ns][key];
            throw new KeyNotFoundException();
        }
        set
        {
            if (!_dict.ContainsKey(ns))
                _dict[ns] = new Dictionary<string, T>();
            _dict[ns][key] = value;
        }
    }

    public T this[string name]
    {
        get
        {
            var tuple = Split(name);
            return this[tuple.Item1, tuple.Item2];
        }
        set
        {
            var tuple = Split(name);
            this[tuple.Item1, tuple.Item2] = value;
        }
    }

    public ICollection<string> Keys
    {
        get { return _dict.SelectMany(p => p.Value.Keys).ToArray(); }
    }

    public ICollection<T> Values
    {
        get { return _dict.SelectMany(p => p.Value.Values).ToArray(); }
    }

    #endregion
}
        var dict = new NamespaceDictionary<int>();
        dict.Add("ns1.var1", 1);
        dict.Add("ns2.var1", 2);
        dict.Add("var2", 3);
        dict.Add("ns2.var2", 4);
        dict.Add("ns3", "var1", 5);
        dict["ns4.var1"] = 6;
        Console.WriteLine(dict["var1"]);
        Console.WriteLine(dict["ns2.var1"]);
        Console.WriteLine(dict["var2"]);
        Console.WriteLine(dict["ns2.var2"]);
        Console.WriteLine(dict["ns2", "var2"]);
        Console.WriteLine(dict["ns3.var1"]);
        Console.WriteLine(dict["ns4", "var1"]);