在C#中使用泛型进行条件比较
在我的场景中,我有两种类型的对象。一个计划和一个层级。每个层共享某些值,而层有3个附加值(速率、最小值和最大值) 我想创建一个通用方法,根据以下条件有条件地评估是否可以将新对象写入数据库: 创建:在C#中使用泛型进行条件比较,c#,asp.net,sql-server,entity-framework,C#,Asp.net,Sql Server,Entity Framework,在我的场景中,我有两种类型的对象。一个计划和一个层级。每个层共享某些值,而层有3个附加值(速率、最小值和最大值) 我想创建一个通用方法,根据以下条件有条件地评估是否可以将新对象写入数据库: 创建: A层:((o1.Rate!=o2.Rate)| |((o1.Start!=o2.Start)&&&(o1.End!=o2.End))&&(MinVal&&MaxVal) 层或计划:(o1.Name!=o2.Name) 层或计划:只有一个可以有(Active==true),其余必须为false 有可能为
((o1.Rate!=o2.Rate)| |((o1.Start!=o2.Start)&&&(o1.End!=o2.End))&&(MinVal&&MaxVal)
(o1.Name!=o2.Name)
(Active==true)
,其余必须为false因此,我有一个对象列表,在将新创建的对象写入数据库之前,我需要将其与数据库中的其他对象进行比较。为了使其工作,通用方法(或类型)需要一个约束,使其能够理解您列出的所有单个属性(
费率
,日期
,最小值
,最大值
,开始
,和结束
)
如果您担心的所有类型都来自同一个基类或接口,那么您不需要泛型,只需构建一个接受该基类的两个参数的方法即可
但是,如果它们不这样做,泛型可能也不适合这里-但是,还有另一种选择。您可以使用
动态使用运行时绑定有效地使用这些属性。请注意,如果您传递的类型参数没有这些属性,它将在运行时失败。可能是这样的:
// I'm making up the types here; modify to match your actual types
public interface IMyObject {
public int Rate { get; set; }
public DateTime Date { get; set; }
public int MinVal { get; set; }
public int MaxVal { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
public static class MyObjectFactory {
public static T Create<T>(int rate, DateTime date, /* etc.. */)
where T : IMyObject, new() {
if (/* tests */) {
throw new MyObjectException("Constraint violated ...");
}
T obj = new T();
obj.Rate = rate;
obj.Date = date;
// etc ....
return obj;
}
}
//我在这里创建类型;修改以匹配您的实际类型
公共接口IMyObject{
公共整数速率{get;set;}
公共日期时间日期{get;set;}
公共int MinVal{get;set;}
公共int MaxVal{get;set;}
公共日期时间开始{get;set;}
公共日期时间结束{get;set;}
}
公共静态类MyObject工厂{
公共静态T创建(整数速率、日期时间日期、/*等…*/)
其中T:IMyObject,new(){
如果(/*测试*/){
抛出新的MyObjectException(“违反约束…”);
}
T obj=新的T();
目标费率=费率;
对象日期=日期;
//等等。。。。
返回obj;
}
}
然后你会这样使用它:
public class SomeMyObject : IMyObject {
// implementation omitted for brevity ...
}
// somewhere:
SomeMyObject obj = MyObjectFactory.Create<SomeMyObject>(rate, date, /* etc. */);
公共类SomeMyObject:IMyObject{
//为简洁起见,省略了实现。。。
}
//某处:
SomeMyObject obj=MyObjectFactory.Create(rate、date、/*等*/);
这就是你想要的吗?你的选择基本上是:
将公共继承基础对象与这些道具一起使用
实现与这些道具的接口
如果对象确实不相关,或者在运行时只知道比较的字段值,则使用反射获取值并进行比较
里德在下面提到了动态对象——这可能行得通,我不得不相信他的答案,但其中包括了动态需求。我真的不确定问题是什么……但如果所有这些都是某种“预先检查”在数据库中创建对象之前,我通常求助于数据库中的存储过程,该过程采用所有相关参数进行创建并返回主键,或者在失败时返回错误代码…如果成功,则使用主键从数据库中加载创建的对象
在这种比较中,数据库通常是非常有效的——如果我需要并行运行程序的多个实例和/或独立于不同的程序创建对象,数据库解决方案会处理它
编辑-根据评论/请求:
我通常与Oracle合作,因此手头没有任何SQL Server存储过程……但这些链接应该提供一些见解:
似乎不太合适,除非我在你的问题中遗漏了一些基本上简单的东西。你想制作一个方法来比较其中两个对象,还是创建其中两个对象?我真的不明白你在这里想要实现什么……这听起来是一个有趣的问题,但我(可能还有其他人)你很难分辨你在问什么,你的例子也很难理解。能否添加一个你希望客户端代码看起来像什么的示例?我将比较一个已经创建的对象和一个我想创建的对象。你如何比较存在的东西和不存在的东西?好吧,如果你看我编辑的帖子,y你会看到我提到,虽然计划和层只共享4个值,而层有3个附加值。要进一步添加,这是使用实体框架-创建的对象是TblPlan/TblTier的形式,因此它不是从基类继承的。所以你是说我可以为SQL server编写一个存储过程,它可以与与用户确认,让他们知道他们的值已经存在?基本上是-存储过程会传回新的主键(=成功创建对象)、错误代码(=由于存在对象而失败)/或者已经存在的“重复对象”的现有主键…然后,您的程序以您想要的任何方式将其传回给用户…您知道我可以使用的任何此类示例吗?我对存储过程了解不多。我通常与Oracle合作,但请参见上面的编辑-链接应为您提供SQL Server的良好起点