前言
最近学习c#
的时候,发现一个非常神奇的语法----dictionary["key"]
,例如拿Dictionary
的值
可以这么拿:
var dictionary = new Dictionary<string,string>();
dictionary.Add("test","test");
Console.WriteLine(dictionary["test"]);
说实话很像javascirpt
的obj['key']
语法。但是如果在c#
中你想这么访问对象
的属性
是不行的:
但是实际上这只是在Dictionary
中加入了Dictionary<TKey,TValue>.Item[TKey] 属性
实现的:
so,我们能否使用这个方式实现
obj["key"]
的形式来访问属性
呢?
实现
首先我们根据Dictionary
的源码来抄一个Item属性
:
class TestItem
{
public string? a { get; set; }
public object this[object key]
{
get
{
return "a";
}
}
}
这里我们用object
来代替泛型
来实现一个类似的Item属性
,然后我们直接访问一下
可以发现顺利的输出了a
,到现在为止,我们简单的为对象
实现了一个obj["key"]
语法。接下来就是为get
关联到对象
正确的属性上,这里比较简单,我们直接使用反射取值
的方式:
class TestItem
{
public string? a { get; set; }
public object? this[string key]
{
get
{
var type = this.GetType();
var propertyInfo = type.GetProperty(key);
var value = propertyInfo?.GetValue(this);
return value;
}
}
}
再测试一遍
可以看到已经可以使用了。
当然,我们还得实现一个set
:
class TestItem
{
public string? a { get; set; }
public object? this[string key]
{
get
{
var type = this.GetType();
var propertyInfo = type.GetProperty(key);
var value = propertyInfo?.GetValue(this);
return value;
}
set
{
var type = this.GetType();
var propertyInfo = type.GetProperty(key);
propertyInfo?.SetValue(this, value);
}
}
}
再来测试一下
可以发现运行成功了,当然我们可以把它抽象成一个抽象类
,来方便使用:
abstract class ItemStatement
{
public virtual object? this[string key]
{
get
{
var type = this.GetType();
var propertyInfo = type.GetProperty(key);
var value = propertyInfo?.GetValue(this);
return value;
}
set
{
var type = this.GetType();
var propertyInfo = type.GetProperty(key);
propertyInfo?.SetValue(this, value);
}
}
}