Я хотел бы записать что-то подобное следующему:
// 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)
{
//d.s = true; //
//d[s] = true; // this format would be ideal
}
Я задавался вопросом, был ли простой способ сделать это, не используя Отражение [.GetProperty(...).GetValue(...,...)
] использование нового ключевого слова C# 4.0: dynamic
.
Кажется, что может быть некоторый путь... Я просто не уверен в точном механизме и не смог найти, что правильный ресурс соединяет все части.
Мысли?
[РЕДАКТИРОВАНИЕ], на которое Это похоже, существует пакет под названием "Глина", которая реализует этот тип функциональности в некотором роде. Глина на CodePlex
Scott Hanselman на предмете
Это можно сделать. Вам просто нужно переопределить TryGetIndex
в DynamicObject
. Мне нужно было что-то подобное для вызова статических членов типа, но, надеюсь, вы уловили идею. Имейте в виду, что в настоящее время это не работает с методами с аргументами универсального типа или методами, которые перегружены, что ограничивает их полезность:
internal class StaticMembersDynamicWrapper : DynamicObject
{
private readonly IDictionary<String, MemberInfo> staticMembers = new Dictionary<string, MemberInfo>();
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);
Нет. dynamic
в C# этого не предлагает. На ваших двух примерах:
d.s = 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
, но это будет намного сложнее, чем просто использовать отражение. Либо используйте отражение (как в вашем примере), либо, если вам нужно оптимизировать его, вы можете обернуть его в делегат, используя Expression
или Delegate.CreateDelegate
.