Bra*_*itz 6 c# dictionary switch-statement
我想构建一个接受字符串参数的方法,以及一个我想根据参数返回特定成员的对象.所以,最简单的方法是构建一个switch语句:
public GetMemberByName(MyObject myobj, string name)
{
switch(name){
case "PropOne": return myobj.prop1;
case "PropTwo": return myobj.prop2;
}
}
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作,但我最终可能会找到一个相当大的列表...所以我很好奇是否有一种方法,没有编写一堆嵌套的if-else结构,以索引方式实现这一点,以便匹配字段通过索引找到而不是通过开关掉落直到找到匹配.
我考虑使用a Dictionary<string, something>来快速访问匹配的字符串(作为关键成员),但由于我想访问传入对象的成员,我不确定如何实现.
我特意试图避免反射等,以便实现非常快速.我可能会使用代码生成,所以解决方案不需要小/紧等.
我最初正在构建一个字典,但每个对象都在初始化它.所以我开始将它移动到一个方法,可以根据键 - 一个switch语句查找值.但由于我不再编入索引,我担心调用此方法的连续查找会很慢.
SO:我正在寻找一种方法来结合索引/散列查找(如字典使用)的性能与返回传入对象的特定属性.我可能会将它放在用于它的每个类中的静态方法中.
这是一个可以适用于任何类的快速模型(使用反射而不是switch语句):
public static object GetMemberByName<T>(T obj, string name)
{
PropertyInfo prop = typeof(T).GetProperty(name);
if(prop != null)
return prop.GetValue(obj, null);
throw new ArgumentException("Named property doesn't exist.");
}
Run Code Online (Sandbox Code Playgroud)
或者扩展方法版本(它仍适用于任何对象类型):
public static object GetMemberByName<T>(this T obj, string name)
{
PropertyInfo prop = typeof(T).GetProperty(name);
if(prop != null)
return prop.GetValue(obj, null);
throw new ArgumentException("Named property doesn't exist.");
}
Run Code Online (Sandbox Code Playgroud)
显然,你可能想要做一些额外的错误检查,但这将是一个开始.
我还从方法中返回了类型对象,原因很简单.这允许调用者处理他们认为合适的值(如果他们需要完全投射).
这是一种可以使用字典的简单方法:
Dictionary<string, Func<MyObject, object>> propertyNameAssociations;
private void BuildPropertyNameAssociations()
{
propertyNameAssociations = new Dictionary<string, Func<MyObject, object>>();
propertyNameAssociations.Add("PropOne", x => x.prop1);
propertyNameAssociations.Add("PropTwo", x => x.prop2);
}
public object GetMemberByName(MyObject myobj, string name)
{
if (propertyNameAssociations.Contains(name))
return propertyNameAssociations[name](myobj);
else
return null;
}
Run Code Online (Sandbox Code Playgroud)
您可以尝试一些选项.
选项1:让对象动态存储属性值.
public GetMemberByName(MyObject myobj, string name)
{
return myobj.GetProperty(name);
}
public class MyObject
{
private Dictionary<string, object> m_Properties = new Dictionary<string, object>();
public object GetProperty(string name)
{
return m_Properties[name];
}
public void SetProperty(string name, object value)
{
m_Properties[name] = value;
}
public object Prop1
{
get { return GetProperty("PropOne"); }
set { SetProperty("PropOne", value); }
}
public object Prop2
{
get { return GetProperty("PropTwo"); }
set { SetProperty("PropTwo", value); }
}
}
Run Code Online (Sandbox Code Playgroud)
选项2:使用反射.
public GetMemberByName(MyObject myobj, string name)
{
return typeof(MyObject).GetProperty(name).GetValue(obj, null);
}
Run Code Online (Sandbox Code Playgroud)
选项3:保持原样.
这是一个合理的选择,因为Dictionary一旦数字case语句达到某个阈值,字符串数据类型的switch语句将转换为查找.C#3.0编译器的阈值为7.因此,无论有多少个案例陈述,查找都将是O(1).它不会扫描每一个.