我有一个这样的课程:
public class SomeClass
{
private const string sessionKey = "__Privileges";
public Dictionary<int, Privilege> Privileges
{
get
{
if (Session[sessionKey] == null)
{
Session[sessionKey] = new Dictionary<int, Privilege>();
}
return (Dictionary<int, Privilege>)Session[sessionKey];
}
}
}
现在,如果我这样......
var someClass = new SomeClass();
var p = someClass.Privileges[13];
...并且没有键13,我会收到这样的错误:
The given key was not present in the dictionary.
我希望有一个可以像上面一样访问的属性,但是如果没有密钥,它将返回一个默认对象。
我尝试创建像这样的索引器属性......
public Privilege Privileges[int key]
{
get
{
try { return _privileges[key]; }
catch { return new Privilege(); }
}
}
...但看起来这不是C#2008语言功能。
如何以相同方式访问属性,但如果密钥不存在则获取默认对象?
答案 0 :(得分:6)
C#不支持命名索引器,正如您所发现的那样。
您是否考虑过使用常规方法而不是索引器属性?并非每个编程问题都需要使用精确的语法来解决。是的,您可以使用聚合字典创建自己的IDictionary实现并更改属性访问行为 - 但是对于只提取值或返回默认值的内容,这是非常必要的吗?
我会在你的班级中添加这样的方法:
protected Privilege GetPrivilege(int key)
{
try { return _privileges[key]; }
catch { return new Privilege(); }
}
或者更好的是,避免将异常处理作为流控制机制:
protected Privilege GetPrivilge( int key )
{
Privilege priv;
if( _privileges.TryGetValue( key, out priv ) )
return priv;
else
return new Privilege();
}
答案 1 :(得分:5)
您必须使用具有所需行为的索引器定义自己的基于IDictionary的类,并在属性getter中返回该实例,而不是库存Dictionary类。
答案 2 :(得分:2)
this
关键字一起使用。
我怀疑你想要这样的东西:
public Privilege this[int key]
{
get
{
try { return _privileges[key]; }
catch { return default(Privelege); }
}
}
您可以直接在SomeClass
中定义,以便您可以访问以下项目:
SomeClass foo;
var bar = foo[100];
或在从IDictionary<TKey, TValue>
实现的自定义类中定义此索引器(并在内部包含Dictionary<TKey, TValue
以实际存储数据)。然后你可以使用它:
SomeClass foo;
var bar = foo.Priveleges[100];
您似乎建议使用哪种语法,哪种语言可能最合适,但需要花费更多精力。
答案 3 :(得分:-1)
您应该使用此语法来检索值:
public Privilege this[int key]
{
get
{
var value = (Privilege)null;
if(!_privileges.TryGetValue(key, out value))
value = new Privilege();
return value;
}
}
我需要很多这种IDictionary的使用,所以我做了一些扩展方法:
public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key)
{
TValue v = default(TValue);
d.TryGetValue(key, out v);
return v;
}
public static TValue Get<TKey, TValue>(this IDictionary<TKey, TValue> d, TKey key, Func<TValue> value)
{
TValue v = d.Get(key);
if (v == null)
{
v = value();
d.Add(key, v);
}
return v;
}
现在你可以写:
public Privilege this[int key]
{
get
{
return _privileges.Get(key, () => new Privilege());
}
}