如何覆盖动态对象 属性 的获取访问器
How to override get accessor of a dynamic object's property
假设我有以下 class:
public class Person {
public string Name { get; set; }
public string Surname { get; set; }
public string FullName {
get {
return Name + " " + Surname;
}
}
}
以下区块:
Person person = new Person();
person.Name = "Matt";
person.Surname = "Smith";
return person.FullName;
会 return Matt Smith
.
让我们将 Person
类型更改为动态 ExpandoObject
。
代码如下所示:
dynamic person = new ExpandoObject();
person.Name = "Matt";
person.Surname = "Smith";
但这就是我被困的地方。如何覆盖新 FullName
属性 的 get
访问器?
我可以创建一个新方法来达到同样的效果:
person.GetFullName = (Func<string>)(() => {
return person.Name + " " + person.Surname;
});
但这最终会得到一个方法而不是 属性,因此这样称呼它:
person.GetFullName();
编辑
请注意,我不想知道如何定义或创建新动态 属性。我想知道如何覆盖或定义动态 属性.
的 get 访问器
我想象的代码可以是这样的:
person.FullName.get = (Func<string>)(() => {
return person.Name + " " + person.Surname;
});
然后,像这样调用:
Console.WriteLine(person.FullName); //Prints out "Matt Smith"
public class SampleDynamicObject : DynamicObject
{
Dictionary<string, object> values = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "Fullname")
{
result = values["Name"] + " " + values["Surname"];
return true;
}
result = values[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
values[binder.Name] = value;
return true;
}
}
试一试
public class MyDynamic : DynamicObject
{
private Dictionary<string,object> obj = new Dictionary<string, object>();
public Func<string,dynamic,object> PropertyResolver { get; set; }
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (obj.ContainsKey(binder.Name))
{
result = obj[binder.Name];
return true;
}
if (PropertyResolver != null)
{
var actResult = PropertyResolver(binder.Name, this);
result = actResult;
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
obj[binder.Name] = value;
return true;
}
}
static void Main(string[] args)
{
dynamic person = new MyDynamic();
person.Name = "Matt";
person.Surname = "Smith";
person.PropertyResolver = (Func<string, dynamic, object>)
((string name, dynamic me) => { return name == "FullName" ? me.Name + me.Surname : ""; });
Console.WriteLine(person.FullName);
}
public class SampleDynamicObject : DynamicObject
{
Dictionary<string, Func<dynamic, object>> customFieldHandlers = new Dictionary<string, Func<dynamic, object>>();
Dictionary<string, object> values = new Dictionary<string, object>();
public void Get(string property, Func<dynamic, object> handler)
{
customFieldHandlers.Add(property, handler);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (customFieldHandlers.ContainsKey(binder.Name))
{
result = customFieldHandlers[binder.Name](this);
return true;
}
result = values[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
values[binder.Name] = value;
return true;
}
}
dynamic sampleObject = new SampleDynamicObject();
sampleObject.Get("FullName", (Func<dynamic, object>)((o) =>
{
dynamic obj = o;
return o.Name + " " + o.Surname;
}));
dynamic person = new GetterExpando();
person.Name = "Matt";
person.Surname = "Smith";
person.FullName = new GetterExpando.Getter(x => x.Name + " " + x.Surname);
Console.WriteLine(person.FullName); // Matt Smith
// ...
public sealed class GetterExpando : DynamicObject
{
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_data[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object value;
if (_data.TryGetValue(binder.Name, out value))
{
var getter = value as Getter;
result = (getter == null) ? value : getter(this);
return true;
}
return base.TryGetMember(binder, out result);
}
public delegate object Getter(dynamic target);
}
假设我有以下 class:
public class Person {
public string Name { get; set; }
public string Surname { get; set; }
public string FullName {
get {
return Name + " " + Surname;
}
}
}
以下区块:
Person person = new Person();
person.Name = "Matt";
person.Surname = "Smith";
return person.FullName;
会 return Matt Smith
.
让我们将 Person
类型更改为动态 ExpandoObject
。
代码如下所示:
dynamic person = new ExpandoObject();
person.Name = "Matt";
person.Surname = "Smith";
但这就是我被困的地方。如何覆盖新 FullName
属性 的 get
访问器?
我可以创建一个新方法来达到同样的效果:
person.GetFullName = (Func<string>)(() => {
return person.Name + " " + person.Surname;
});
但这最终会得到一个方法而不是 属性,因此这样称呼它:
person.GetFullName();
编辑
请注意,我不想知道如何定义或创建新动态 属性。我想知道如何覆盖或定义动态 属性.
的 get 访问器我想象的代码可以是这样的:
person.FullName.get = (Func<string>)(() => {
return person.Name + " " + person.Surname;
});
然后,像这样调用:
Console.WriteLine(person.FullName); //Prints out "Matt Smith"
public class SampleDynamicObject : DynamicObject
{
Dictionary<string, object> values = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name == "Fullname")
{
result = values["Name"] + " " + values["Surname"];
return true;
}
result = values[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
values[binder.Name] = value;
return true;
}
}
试一试
public class MyDynamic : DynamicObject
{
private Dictionary<string,object> obj = new Dictionary<string, object>();
public Func<string,dynamic,object> PropertyResolver { get; set; }
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (obj.ContainsKey(binder.Name))
{
result = obj[binder.Name];
return true;
}
if (PropertyResolver != null)
{
var actResult = PropertyResolver(binder.Name, this);
result = actResult;
return true;
}
return base.TryGetMember(binder, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
obj[binder.Name] = value;
return true;
}
}
static void Main(string[] args)
{
dynamic person = new MyDynamic();
person.Name = "Matt";
person.Surname = "Smith";
person.PropertyResolver = (Func<string, dynamic, object>)
((string name, dynamic me) => { return name == "FullName" ? me.Name + me.Surname : ""; });
Console.WriteLine(person.FullName);
}
public class SampleDynamicObject : DynamicObject
{
Dictionary<string, Func<dynamic, object>> customFieldHandlers = new Dictionary<string, Func<dynamic, object>>();
Dictionary<string, object> values = new Dictionary<string, object>();
public void Get(string property, Func<dynamic, object> handler)
{
customFieldHandlers.Add(property, handler);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (customFieldHandlers.ContainsKey(binder.Name))
{
result = customFieldHandlers[binder.Name](this);
return true;
}
result = values[binder.Name];
return true;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
values[binder.Name] = value;
return true;
}
}
dynamic sampleObject = new SampleDynamicObject();
sampleObject.Get("FullName", (Func<dynamic, object>)((o) =>
{
dynamic obj = o;
return o.Name + " " + o.Surname;
}));
dynamic person = new GetterExpando();
person.Name = "Matt";
person.Surname = "Smith";
person.FullName = new GetterExpando.Getter(x => x.Name + " " + x.Surname);
Console.WriteLine(person.FullName); // Matt Smith
// ...
public sealed class GetterExpando : DynamicObject
{
private readonly Dictionary<string, object> _data = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_data[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object value;
if (_data.TryGetValue(binder.Name, out value))
{
var getter = value as Getter;
result = (getter == null) ? value : getter(this);
return true;
}
return base.TryGetMember(binder, out result);
}
public delegate object Getter(dynamic target);
}