用显式方法按类型对API进行通用包装



我正在寻找一种基于类型或类型集轻松管理决策的方法。(例如,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,因为我们不知道它将是什么类型-这就是为什么我更喜欢具有两个泛型参数的方法。

相关内容

  • 没有找到相关文章