我正在寻找一种基于类型或类型集轻松管理决策的方法。(例如,if是string, double等做一件事,if是enum做另一件事,等等)。我有一个重要性和可维护性都至关重要的横截面。
我正在使用一个强制遵循以下约定的API。
double dblField;
if(!apiObj.IsNull("NameOfDOubleProperty"))
dblefield = apiObj.GetDouble("NameOfDOubleProperty");
string stringField;
if(!apiObj.IsNull("NameOfStringProperty"))
stringField = apiObj.GetDouble("NameOfStringProperty");
//Repeat for each property
我讨厌代码中到处都是魔法字符串。如果我在应用程序中改变了一些东西,那么我必须添加另一个,或者更糟的是,记得重命名每个地方。
Step1:在启动时,获取只读静态字段(由单个时间反射调用生成)。我有。
步骤2:我的问题-如果它是一个字符串,双精度,或其他常见的原语,我有一个泛型apiobj。我可以强制转换的GetField。但是,对于某些对象,我需要特殊处理。
思想还是模式?
我会考虑将你的字符串文字转换为常量。
const string NAME_OF_DOUBLE_PROPERTY = "NameOfDOubleProperty";
const string NAME_OF_STRING_PROPERTY = "NameOfStringProperty";
那至少能帮上忙。
通过上面的步骤1,我假设这是一个设置为从API接收数据的所有字段的列表。
我想我会从创建一个自定义属性来装饰字段开始:
[ApiProperty(NAME_OF_DOUBLE_PROPERTY)]
double dblField;
这样api属性名和接收字段就保持在一起了。现在,基本上在一个地方,你有接收字段,api属性的名称和类型(通过FieldInfo
类和它的CustomAttributes
属性从你的Step1)。
您可以使用表达式使用实际的属性名,并使用辅助方法:
public static string GetPropertyName<T>(Expression<Func<T, object>> expression)
{
var body = expression.Body;
if (body is UnaryExpression)
{
var unaryExpression = body as UnaryExpression;
if (unaryExpression.Operand is MemberExpression)
return (unaryExpression.Operand as MemberExpression).Member.Name;
}
if (body is MemberExpression)
{
return (body as MemberExpression).Member.Name;
}
return null;
}
那么你可以调用
double dblField;
if(!apiObj.IsNull(GetPropertyName<YourObject>(o=>o.NameOfDoubleProperty))
dblefield = apiObj.GetDouble(GetPropertyName<YourObject>(o=>o.NameOfDoubleProperty));
或者你可以在你的api中使用GetPropertyName方法,即
dblefield = apiObj.GetDouble<YourObject>(o=>o.NameOfDoubleProperty);
的方式,你不会有任何神奇的字符串,可以使用实际的属性名称,这将使重构和维护容易得多。
第二步你可以输入:
dblefield = apiObj.GetField<YourObject, double>(o=>o.NameOfDoubleProperty);
和你的GetField<TObj, TType>(.....)
:
if(gottenValue is TType)
return (TType)gottenValue;
你可以得到YourObject属性的类型。
:public static Type GetPropertyType<T>(Expression<Func<T, object>> expression)
{
var body = expression.Body;
MemberInfo mi = null;
if (body is UnaryExpression)
{
var unaryExpression = body as UnaryExpression;
if (unaryExpression.Operand is MemberExpression)
mi = (unaryExpression.Operand as MemberExpression).Member;
}
else if (body is MemberExpression)
{
mi = (body as MemberExpression).Member;
}
if(mi is PropertyInfo)
{
return (mi as PropertyInfo).PropertyType;
}
return null;
}
但是我不知道你如何以一种有用的方式使用这种类型,即你可以通过反射转换为返回的类型(虽然不知道性能)
dbleField = Convert.ChangeType(yourValue, GetPropertyType<YourObject>(o=>o.NameOfDoubleProperty);
或在您的api方法中具有此功能-然而,此方法必须返回object
,因为我们不知道它将是什么类型-这就是为什么我更喜欢具有两个泛型参数的方法。