这是对泛型和c# '动态数据类型的恰当使用吗?

本文关键字:数据类型 动态 泛型 | 更新日期: 2023-09-27 18:02:10

我遇到的问题是,我们正在使用现有的ORM(它是一个叫做Gentle的旧ORM)构建一个数据访问层,并打算迁移到像Fluent NHibernate这样的东西。在一些查询中,我们必须在现有的设置中向SqlBuilder添加自定义子句,因此,例如,当检索某些person对象时,我们可能会添加这样的子句:

"PersonId in (SELECT PersonId from Orders where OrderValue > " + orderValue + " and OrderName = " + orderName

关键是参数直接添加到字符串中,而不是作为参数化查询,在Gentle中可以将其添加为参数化查询,这就是我一直在做的。我们所有的DALs都继承自一个基本的GentleDAL,这个类实际上构造了Gentle查询,添加了子句和参数等。要在Gentle中添加参数化子句,您必须使用SqlBuilder对象做两件事,您必须调用sb.AddConstraint(string clause)来添加您的子句,然后对于每个参数,您必须调用sb.AddParameter(string name, Type type),然后您可以从中构建您的SqlStatement对象,只有在此之后才能设置您调用stmt.SetParameter(string name, object value)的参数值。

我表示这些参数/子句的方式是我已经创建了一个名为GentleClauseCollection的类,它包含子句和参数,并为这些东西都有Add和Get方法。子句只是字符串,内部存储在List中,参数存储在使用泛型的绅士参数类中。绅士参数的完整代码如下:

public class GentleParameter<TParamType>
{       
    public string Name { get; private set; }
    public TParamType Value { get; private set; }
    public Type ParameterType  {get { return typeof (TParamType); }}
    public GentleParameter(string parameterName, TParamType parameterValue)
    {
        Name = parameterName;
        Value = parameterValue;
    }
}

在。net中,我知道没有集合可以让我在同一个集合中存储TParamType的不同值的绅士参数,但是它可以使用DLR完成。在我的GentleCollection类中,我将参数存储在一个List中,并以IEnumerable的形式从这个类中获取参数。我的类中的Add方法只能允许添加绅士参数,所以我知道我的参数总是有一个我可以访问的Name, Value和ParameterType字段。

我的问题是:考虑到我可以牺牲泛型和改变我的参数类值属性为"对象"而不是T,我是否通过使用动态过于复杂的事情,这两种方法的优缺点是什么?是否有第三种方法可以做到这一点,我还没有想到,我可能看到使用动态的性能影响有多显著,因为使用动态对象的所有方法调用将在运行时编译?

提前感谢您的帮助。

这是对泛型和c# '动态数据类型的恰当使用吗?

由于sb.SetParameter不是通用的,等待object,因此我不会使GentleParameter通用,因此我不会使用DLR。

使用动态对我来说似乎并不复杂。方法调用在运行时被解析并被缓存,结果调用可能平均慢10倍(我们说的是纳秒)。所以这取决于你如何使用它,如果它有意义的话。

如果你总是使用它作为Object类型,那么是的,你不需要使用动态类型,这不会伤害任何东西。

如果您希望能够访问属性,那么您应该使用动态,结果代码将比您可以做的任何其他事情看起来更干净。

但是即使使用动态,你也不一定要动态地调用属性本身,如果你想要尽可能多的静态类型,你可以动态解析一个helper方法,它采用你的绅士参数的通用形式,并在其中完成你的工作。

 ...
private void HelperDoStuffWithGenericParam<T>(GentleParameter<T>param){
        //Do stuff you have the static typing
}