C# 名称空间dict?
我正在设计一种模板语言。其中有3种标记:标记、指令和变量。这些代币中的每一个都有一个名字,而且会有相当多的代币。它们也是可扩展的 为了允许名称重用,我想添加名称空间 现在所有变量都存储在一个dict中。键是变量名,值是变量值。这样我可以快速检索变量的值。但是,假设我想允许点表示法,C# 名称空间dict?,c#,C#,我正在设计一种模板语言。其中有3种标记:标记、指令和变量。这些代币中的每一个都有一个名字,而且会有相当多的代币。它们也是可扩展的 为了允许名称重用,我想添加名称空间 现在所有变量都存储在一个dict中。键是变量名,值是变量值。这样我可以快速检索变量的值。但是,假设我想允许点表示法,namespace.variable,我如何存储这些变量,以便名称空间是可选的?如果包含名称空间,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"]);