如何覆盖动态对象属性的get访问器

我们假设我有以下课程:

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; 

Matt Smith会回来的。

让我们将Person类型更改为动态ExpandoObject

代码如下所示:

 dynamic person = new ExpandoObject(); person.Name = "Matt"; person.Surname = "Smith"; 

但这就是我被困的地方。 如何覆盖新FullName属性的get访问器?

我可以实现创建新方法的相同效果:

 person.GetFullName = (Func)(() => { return person.Name + " " + person.Surname; }); 

但这最终会得到一个方法,而不是一个属性,因此称之为:

 person.GetFullName(); 

编辑

请注意,我不想知道如何定义或创建新的动态属性。 我想知道如何覆盖或定义动态属性的get访问器。

我认为代码可以是这样的:

 person.FullName.get = (Func)(() => { return person.Name + " " + person.Surname; }); 

然后,像这样调用:

 Console.WriteLine(person.FullName); //Prints out "Matt Smith" 

 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 _data = new Dictionary(); 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); } 
 public class SampleDynamicObject : DynamicObject { Dictionary> customFieldHandlers = new Dictionary>(); Dictionary values = new Dictionary(); public void Get(string property, Func 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)((o) => { dynamic obj = o; return o.Name + " " + o.Surname; })); 

试试吧

  public class MyDynamic : DynamicObject { private Dictionary obj = new Dictionary(); public Func 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 name, dynamic me) => { return name == "FullName" ? me.Name + me.Surname : ""; }); Console.WriteLine(person.FullName); } 
 public class SampleDynamicObject : DynamicObject { Dictionary values = new Dictionary(); 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; } }