C#使用Dynamic关键字通过字符串访问属性而不进行reflection

我想写类似以下内容:

// I will pass in a number of "properties" specified as strings that I want modified string[] properties = new [] { "AllowEdit", "AllowDelete" }; // Casting the component I'm using to a dynamic object of some sort ? dynamic d = myGridComponent; // Iterate over the strings and set the properties foreach(var s in properties) { //ds = true; // //d[s] = true; // this format would be ideal } 

我想知道是否有一种简单的方法来做这个,而不使用reflection[ .GetProperty(...).GetValue(...,...) ]使用新的C#4.0关键字: dynamic

似乎可能有某种方式,…我只是不确定确切的机制,并且无法找到合适的资源来将所有部分组合在一起。

想法?

[编辑]看起来有一个名为“Clay”的包以某种方式实现了这种类型的function。 粘贴在CodePlex上
关于主题的斯科特汉塞尔曼

可以办到。 您只需要在DynamicObject上覆盖TryGetIndex 。 我需要类似的东西来调用一个类型的静态成员,但希望你能得到这个想法。 请注意,这当前不适用于具有generics类型参数的方法或过载的方法,从而限制了它的实用程序:

 internal class StaticMembersDynamicWrapper : DynamicObject { private readonly IDictionary staticMembers = new Dictionary(); private readonly Type type; public StaticMembersDynamicWrapper(Type type) { this.type = type; type.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Public) .Each(member => staticMembers[member.Name] = member); } public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { var name = indexes[0] as string; MemberInfo member; if (false == staticMembers.TryGetValue(name, out member)) { result = null; return false; } var prop = member as PropertyInfo; if (prop != null) { result = prop.GetValue(null, null); return true; } var method = member as MethodInfo; if (method != null) { var parameterTypes = (from p in method.GetParameters() select p.ParameterType).ToArray(); var delegateType = method.ReturnType != typeof (void) ? Expression.GetFuncType(parameterTypes.Union(new[]{method.ReturnType}).ToArray()) : Expression.GetActionType(parameterTypes); result = Delegate.CreateDelegate(delegateType, method); return true; } result = null; return false; } } dynamic d = new StaticMembersDynamicWrapper(typeof(string)); var result = d["IsNullOrEmpty"](String.Empty); 

C#中的dynamic不具备此function。 用你的两个例子:

 ds = true; // this looks for a property or field called "s" d[s] = true; // this looks for an indexer that matches the string/bool signature 

可以编写dynamic提供的相同代码,但这比使用reflection要困难得多。 使用reflection(根据您的示例),或者如果您需要优化它,您可以选择通过ExpressionDelegate.CreateDelegate将其包装在Delegate.CreateDelegate

通过nuget提供的开源框架Impromptu-interface封装了动态以完全动态的方式生成的代码。 它不如使用动态关键字快 ,但比reflection更快 。

 foreach(var s in properties) { //ds = true; Impromptu.InvokeSet(d, s, true); }