DynamicObject
在 .NET 中,DynamicObject 是一个抽象类,位于 System.Dynamic 命名空间下,用于实现动态行为的对象。通过继承 DynamicObject 类并重写其方法,可以自定义对象的行为,使其能够响应动态调用,如属性访问、方法调用等。以下是 DynamicObject 的一些关键特性和用途:
动态行为:
允许对象在运行时决定如何响应属性和方法调用。
适用于需要灵活处理对象的情况,例如动态数据绑定、脚本引擎集成等。
主要方法:
- TryGetMember(GetMemberBinder binder, out object result):处理获取属性值的操作。
- TrySetMember(SetMemberBinder binder, object value):处理设置属性值的操作。
- TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result):处理方法调用的操作。
- TryConvert(ConvertBinder binder, out object result):处理类型转换的操作。
- TryInvoke(InvokeBinder binder, object[] args, out object result):处理对象本身作为方法调用的操作。
- TryDeleteMember(DeleteMemberBinder binder):处理删除属性的操作。
- TryGetIndex(GetIndexBinder binder, object[] indexes, out object result):处理索引器获取值的操作。
- TrySetIndex(SetIndexBinder binder, object[] indexes, object value):处理索引器设置值的操作。
例:
using System;
using System.Collections.Generic;
using System.Dynamic;
public class MyDynamicObject : DynamicObject
{
private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
// 处理获取属性值的操作
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _properties.TryGetValue(binder.Name, out result);
}
// 处理设置属性值的操作
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_properties[binder.Name] = value;
return true;
}
// 处理方法调用的操作
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
switch (binder.Name)
{
case "SayHello":
if (args.Length == 1 && args[0] is string name)
{
result = $"Hello, {name}!";
return true;
}
break;
case "Add":
if (args.Length == 2 && args[0] is int a && args[1] is int b)
{
result = a + b;
return true;
}
break;
}
result = null;
return false;
}
// 处理类型转换的操作
public override bool TryConvert(ConvertBinder binder, out object result)
{
if (binder.Type == typeof(string))
{
result = "This is a dynamic object";
return true;
}
result = null;
return false;
}
// 处理对象本身作为方法调用的操作
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
if (args.Length == 1 && args[0] is string message)
{
result = $"Invoked with message: {message}";
return true;
}
result = null;
return false;
}
// 处理删除属性的操作
public override bool TryDeleteMember(DeleteMemberBinder binder)
{
if (_properties.ContainsKey(binder.Name))
{
_properties.Remove(binder.Name);
return true;
}
return false;
}
// 处理索引器获取值的操作
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1 && indexes[0] is string key)
{
return _properties.TryGetValue(key, out result);
}
result = null;
return false;
}
// 处理索引器设置值的操作
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
{
if (indexes.Length == 1 && indexes[0] is string key)
{
_properties[key] = value;
return true;
}
return false;
}
}
public class Program
{
public static void Main()
{
dynamic myObj = new MyDynamicObject();
// 设置和获取属性
myObj.Name = "World";
Console.WriteLine(myObj.Name); // 输出: World
// 调用方法
Console.WriteLine(myObj.SayHello("Friend")); // 输出: Hello, Friend!
Console.WriteLine(myObj.Add(3, 5)); // 输出: 8
// 类型转换
string objString = (string)myObj;
Console.WriteLine(objString); // 输出: This is a dynamic object
// 对象本身作为方法调用
Console.WriteLine(myObj("Hello, Dynamic!")); // 输出: Invoked with message: Hello, Dynamic!
// 删除属性
myObj.DeleteName();
Console.WriteLine(myObj.Name ?? "Name not found"); // 输出: Name not found
// 索引器操作
myObj["Key1"] = "Value1";
Console.WriteLine(myObj["Key1"]); // 输出: Value1
}
}
项目中的应用