我正在寻找一种基于类型或类型集轻松管理决策的方法。 (例如,if是string,double等做一件事,如果是枚举做别的事等)。我有一个重要性和可维护性的横截面是至关重要的。
我正在使用强制执行以下约定的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
I LOATHE魔法字符串遍布代码。如果我在应用程序中更改某些内容我正在阅读此内容,那么我必须添加另一个内容,或者更糟糕的是记住重命名每个地方。
步骤1:启动时,获取只读静态字段(由单次反射调用生成)。我有。
第2步:我的问题 - 如果它是一个字符串,双精度或其他常见原语,我有一个我可以强制转换的通用apiobj.GetField。但是,对于某些对象,我需要特殊处理。
思想或模式?
答案 0 :(得分:2)
我会考虑将你的字符串文字转换为常量..
const string NAME_OF_DOUBLE_PROPERTY = "NameOfDOubleProperty";
const string NAME_OF_STRING_PROPERTY = "NameOfStringProperty";
至少,这将有助于打字错误。
通过上面的Step1,我假设这是设置为从API接收数据的所有字段的列表。
我想我会先创建一个自定义属性来装饰字段:
[ApiProperty(NAME_OF_DOUBLE_PROPERTY)]
double dblField;
这样,api属性名称和接收字段保持在一起。
现在,基本上在一个位置,您有接收字段,api属性的名称和类型(通过Step1中的FieldInfo
类及其CustomAttributes
属性)。
其余部分对你来说应该是微不足道的。
答案 1 :(得分:2)
您可以使用表达式使用实际属性名称,并使用辅助方法:
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);
这样你就不会有任何神奇的字符串,并且可以使用实际的属性名称,这将使重构和维护变得更加容易。
然后对于第2步,您可以:
dblefield = apiObj.GetField<YourObject, double>(o=>o.NameOfDoubleProperty);
并在GetField<TObj, TType>(.....)
内:
if(gottenValue is TType)
return (TType)gottenValue;
您可以使用以下方法从表达式中获取属性YourObject.NameOfDoubleProperty的类型:
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;
}
但是我不知道如何以有用的方式使用该类型,即你可以通过Reflection转换为返回的类型(尽管dunno关于性能)
dbleField = Convert.ChangeType(yourValue, GetPropertyType<YourObject>(o=>o.NameOfDoubleProperty);
或在api方法中使用此功能 - 但是此方法必须返回object
,因为我们不知道它将是什么类型 - 这就是为什么我更喜欢使用两个通用参数的方法。< / p>