dynamic动态应用-静态成员的动态封装类
静态成员的动态封装类
dynamic dynamic = new StaticMemberDynamicWrapper(typeof(string));
// 动态调用静态方法
var r = dynamic.Concat("A", "B");
Console.WriteLine(r);
if (r.Contains("A"))
{
Console.WriteLine(\("{r} Contains A"); } else { Console.WriteLine(\)"{r} Not Contains A");
}
/// <summary>
/// 静态成员的动态封装类
/// </summary>
internal sealed class StaticMemberDynamicWrapper : DynamicObject
{
private readonly TypeInfo _typeInfo;
public StaticMemberDynamicWrapper(Type type)
{
_typeInfo = type.GetTypeInfo();
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _typeInfo.DeclaredMembers.Select(s => s.Name);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
var field = FindField(binder.Name);
if (field != null)
{
result = field.GetValue(null);
return true;
}
var prop = FindProperty(binder.Name, true);
if (prop != null)
{
result = prop.GetValue(null, null);
return true;
}
return false;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var field = FindField(binder.Name);
if (field != null)
{
field.SetValue(null, value);
return true;
}
var prop = FindProperty(binder.Name, false);
if (prop != null)
{
prop.SetValue(null, value, null);
return true;
}
return false;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
MethodInfo method = FindMethod(binder.Name, args.Select(s => s.GetType()).ToArray());
if (method == null)
{
result = null;
return false;
}
result = method.Invoke(null, args);
return true;
}
private MethodInfo FindMethod(string name, Type[] paramTypes)
{
return _typeInfo.DeclaredMethods.FirstOrDefault(x => x.Name == name
&& x.IsPublic && x.IsStatic && ParametersMatch(x.GetParameters(), paramTypes));
}
private bool ParametersMatch(ParameterInfo[] parameterInfos, Type[] paramTypes)
{
if (parameterInfos.Length != paramTypes.Length)
{
return false;
}
for (int i = 0; i < parameterInfos.Length; i++)
{
if (parameterInfos[i].ParameterType != paramTypes[i])
{
return false;
}
}
return true;
}
private PropertyInfo FindProperty(string name, bool get)
{
if (get)
{
return _typeInfo.DeclaredProperties.FirstOrDefault(x => x.Name == name
&& x.GetMethod != null && x.GetMethod.IsPublic && x.GetMethod.IsStatic);
}
return _typeInfo.DeclaredProperties.FirstOrDefault(x => x.Name == name
&& x.SetMethod != null && x.SetMethod.IsPublic && x.SetMethod.IsStatic);
}
private FieldInfo FindField(string name)
{
return _typeInfo.DeclaredFields.FirstOrDefault(x => x.IsPublic && x.IsStatic && x.Name == name);
}
}
动态参数类型
public ObservableCollection<DynamicParaRow> ItemsSourceData { get; private set; }
dynamic model = new DynamicParaModel();
DynamicParaRow row = new DynamicParaRow("name", model);
ItemsSourceData.Add(row);
// 属性动态变化
foreach (var row in ItemsSourceData)
{
row.DynamicParaModel.PropertyName = item.ParaName;
row.DynamicParaModel.PropertyValue = item.ParaValue;
}
public class DynamicParaRow : NotifyPropertyChangedEx
{
public DynamicParaRow(string name, DynamicParaModel model)
{
IsCheck = false;
PropertyName1 = name;
DynamicParaModel = model;
}
/// <summary>
/// 属性名称
/// </summary>
public string PropertyName1 { get; set; }
private bool _isCheck;
/// <summary>
/// 是否可勾选
/// </summary>
public bool IsCheck
{
get { return _isCheck; }
set { UpdateProperty(ref _isCheck, value); }
}
private DynamicParaModel _dynamicParaModel;
public DynamicParaModel DynamicParaModel
{
get { return _dynamicParaModel; }
set { UpdateProperty(ref _dynamicParaModel, value); }
}
}
/// <summary>
/// 动态参数类型
/// </summary>
public class DynamicParaModel : DynamicObject, INotifyPropertyChanged
{
/// <summary>
/// 属性名称
/// </summary>
public string PropertyName { get; set; }
private object _propertyValue;
/// <summary>
/// 属性值
/// </summary>
public object PropertyValue
{
get { return _propertyValue; }
set
{
_propertyValue = value;
_properties[PropertyName] = value;
OnPropertyChanged(PropertyName);
}
}
readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
public void Delete(string propertyName)
{
if (_properties.ContainsKey(propertyName))
{
_properties.Remove(propertyName);
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_properties.Keys.Contains(binder.Name))
{
_properties[binder.Name] = value;
}
else
{
_properties.Add(binder.Name, value);
}
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _properties.TryGetValue(binder.Name, out result);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
动态添加参数
dynamic的属性直接调用即可。若不知道属性,或属性是根据条件动态生成的,可以通过内置的Dictionary处理。
dynamic obj = new System.Dynamic.ExpandoObject();
string key = "Name";
WSCommFunc.SetDynamicProperty(obj, key, DateTime.Now);
Console.WriteLine("Name: " + GetDynamicProperty(obj, key));
using System;
using System.ComponentModel;
using System.Dynamic;
/// <summary>
/// 动态设置动态属性
/// </summary>
/// <param name="obj">ExpandoObject</param>
/// <param name="propertyName">属性名称</param>
/// <param name="value">属性值</param>
public static void SetDynamicProperty(dynamic obj, string propertyName, object value)
{
var dic = (IDictionary<string, object>)obj;
if (dic.ContainsKey(propertyName))
{
dic[propertyName] = value;
}
else
{
dic.Add(propertyName, value);
}
}
/// <summary>
/// 动态获取动态属性值
/// </summary>
/// <param name="obj">ExpandoObject</param>
/// <param name="propertyName">属性名称</param>
/// <returns></returns>
public static object GetDynamicProperty(dynamic obj, string propertyName)
{
if (obj is IDictionary<string, object> dic && dic.TryGetValue(propertyName, out object value))
{
return value;
}
return default;
}