Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是泛型和C#';什么是动态数据类型?_C#_Generics_C# 4.0_Dynamic_Data Access Layer - Fatal编程技术网

这是泛型和C#';什么是动态数据类型?

这是泛型和C#';什么是动态数据类型?,c#,generics,c#-4.0,dynamic,data-access-layer,C#,Generics,C# 4.0,Dynamic,Data Access Layer,因此,我面临的问题是,我们正在使用现有的ORM(它是一个旧的称为温柔的ORM)构建一个数据访问层,并考虑迁移到类似Fluent NHibernate的东西。在一些查询中,我们必须在现有设置中将自定义子句添加到SqlBuilder中,因此,例如,在检索某些person对象时,我们可能会添加如下子句: "PersonId in (SELECT PersonId from Orders where OrderValue > " + orderValue + " and OrderName = "

因此,我面临的问题是,我们正在使用现有的ORM(它是一个旧的称为温柔的ORM)构建一个数据访问层,并考虑迁移到类似Fluent NHibernate的东西。在一些查询中,我们必须在现有设置中将自定义子句添加到SqlBuilder中,因此,例如,在检索某些person对象时,我们可能会添加如下子句:

"PersonId in (SELECT PersonId from Orders where OrderValue > " + orderValue + " and OrderName = " + orderName
关键是参数直接添加到字符串中,而不是作为参数化查询添加,因此可以将其作为参数化查询添加,这就是我一直在研究的内容。我们所有的DAL都继承自一个基本的
GentleDAL
,这是一个实际构造温和查询、添加子句和参数等的类。要在温和中添加参数化子句,您必须对SqlBuilder对象做两件事,您必须调用
sb.AddConstraint(string子句)
来添加子句,然后,对于您必须调用的每个参数
sb.AddParameter(字符串名称,类型)
,您可以从中构造
SqlStatement
对象,只有在这之后,您才能在调用
stmt.SetParameter(字符串名称,对象值)
的位置设置参数值

我表示这些参数/子句的方式是,我创建了一个名为GentleClauseCollection的类,该类包含子句和参数,并具有用于这两个方面的Add和Get方法。子句只是字符串,存储在列表的内部,参数存储在使用泛型的GentleParameter类中。GentleParameter的完整代码如下所示

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;
    }
}
公共类绅士参数
{       
公共字符串名称{get;private set;}
公共TParamType值{get;private set;}
公共类型参数类型{get{return typeof(TParamType);}
公共GentleParameter(字符串参数名称,TParamType参数值)
{
名称=参数名称;
值=参数值;
}
}
据我所知,在.NET中没有一个集合允许我在同一集合中存储TpamType不同值的GentleParameter,但是可以使用DLR来完成。在我的GentelCollection类中,我将参数存储在一个列表中,并将该类中的参数作为IEnumerable获取。我的类中的Add方法只允许添加GentleParameter,因此我知道我的参数将始终具有名称、值和参数类型字段,我可以访问这些字段

我的问题是:如果我可以牺牲泛型并将参数类值属性改为“object”而不是T,那么我是否通过使用dynamic使事情变得过于复杂,这两种方法的优缺点是什么?如果所有使用动态对象的方法调用都将在运行时编译,那么有没有第三种方法可以做到这一点,我还没有想到,使用动态对象对性能的影响有多大


提前感谢您的帮助。

由于
sb.SetParameter
不是泛型的,并等待
对象
,我不会将
GentleParameter
设置为泛型,因此我不会使用DLR。

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

如果您总是将它用作type
对象,那么您不需要使用type dynamic,这不会造成任何伤害

如果您希望能够访问属性,而不是应该使用dynamic,那么结果代码将比您所能做的任何事情都更干净

但即使使用dynamic,也不一定要动态调用属性本身,如果希望尽可能多地使用静态类型,可以使用dynamic resolve帮助器方法,该方法采用GentelParameter的通用形式,并在其中执行工作

 ...

private void HelperDoStuffWithGenericParam<T>(GentleParameter<T>param){

        //Do stuff you have the static typing
}
。。。
私有void HelperDoStuffWithGenericParam(GentleParameterparam){
//你有静态打字吗
}

谢谢,我怀疑这是共识。+1关于静态类型助手方法的建议似乎很有趣。我将研究一下,看看我的代码是如何处理的。事实上,我认为这是一个很好的解决方案。我不清楚在我的情况下,这将如何工作,因为我有类似的问题。可数参数;foreach(parameters中的var参数){stmt.SetParameter(parameter.Name,parameter.Value);}我不知道如何将参数对象强制转换为GentleParameter,因为我直到运行时才知道它。在循环中调用HelperSetStatementParam(stmt,parameter)——void HelperSetStatementParam(SqlStatement stmt,GentleParameterparameter){stmt.SetParameter(parameter.Name,parameter.Value);}对帮助程序的调用在运行时解析。