Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.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 - Fatal编程技术网

设计建议-如何将这些方法转换为利用C#泛型

设计建议-如何将这些方法转换为利用C#泛型,c#,generics,C#,Generics,在整个应用程序中,我有许多方法可以加载集合。它们都遵循以下模式(实际上大多数都有一些差异): public BaseCollection<ObjectType1> LoadObjectType1(EventHandler handleEvent) { var myQuery = ObjectType1.Load(MyServiceContext); return new DataManager<ObjectType1>().GetData(myQuery

在整个应用程序中,我有许多方法可以加载集合。它们都遵循以下模式(实际上大多数都有一些差异):

public BaseCollection<ObjectType1> LoadObjectType1(EventHandler handleEvent)
{
    var myQuery = ObjectType1.Load(MyServiceContext);
    return new DataManager<ObjectType1>().GetData(myQuery , handleEvent, MyServiceContextt);
}

public BaseCollection<ObjectType2> LoadObjectType2(EventHandler handleEvent)
{
   var myQuery = ObjectType2.Load(MyServiceContext);
   return new DataManager<ObjectType2>().GetData(myQuery , handleEvent, MyServiceContextt);
}

public BaseCollection<ObjectType3> LoadObjectType3(EventHandler handleEvent)
{
   var query = ObjectType3.Load(MyServiceContext);
   return new DataManager<ObjectType3>().GetData(query, handleEvent, MyServiceContextt);
}
public BaseCollection LoadObjectType1(EventHandler handleEvent)
{
var myQuery=ObjectType1.Load(MyServiceContext);
返回新的DataManager().GetData(myQuery、handleEvent、MyServiceContext);
}
public BaseCollection LoadObjectType2(EventHandler handleEvent)
{
var myQuery=ObjectType2.Load(MyServiceContext);
返回新的DataManager().GetData(myQuery、handleEvent、MyServiceContext);
}
public BaseCollection LoadObjectType3(EventHandler handleEvent)
{
var query=ObjectType3.Load(MyServiceContext);
返回新的DataManager().GetData(查询、handleEvent、MyServiceContext);
}
其中ObjectType#是我的业务对象,例如员工、部门等

我想将这些转换为利用泛型


任何建议都将不胜感激。

您始终可以创建这些函数的版本,这些函数本身带有泛型参数。但是,由于没有允许编译器推断泛型参数类型的参数,因此您必须始终在调用中提供它

主要的问题是,您使用的是在每个对象类型上实现的静态
Load
方法。您必须以代理身份将此消息传递给呼叫:

public BaseCollection<T> Load<T>(EventHandler handleEvent, Func<QueryType> querySelector) 
{ 
    var myQuery = querySelector(MyServiceContext); 
    return new DataManager<T>().GetData(myQuery , handleEvent, MyServiceContext); 
}
编辑:那么,既然你已经更新了你的问题,我想我对它的理解要好一点。没有理由不能将不同的方法折叠为一个重载。如果您可以重构实现,使查询不从对象类型检索,那么您就可以进一步改进和整合。工厂模式可以使事物更干净、更易于维护:

public BaseCollection<T> Load<T>(EventHandler handleEvent) 
{ 
    var myQuery = QueryManager.GetQuery<T>(MyServiceContext); 
    return new DataManager<T>().GetData(myQuery , handleEvent, MyServiceContext); 
}
公共基集合加载(EventHandler handleEvent)
{ 
var myQuery=QueryManager.GetQuery(MyServiceContext);
返回新的DataManager().GetData(myQuery、handleEvent、MyServiceContext);
}
您的意思是希望这些方法是通用的吗?像这样的

public BaseCollection<T> LoadObject<T>(EventHandler handleEvent)
{
    var myQuery = BusinessUtil.Load<T>(MyServiceContext);
    return new DataManager<T>().GetData(myQuery, handleEvent, MyServiceContext);
}
或者,您可以在
LoadObject
上要求一个额外的参数来指定如何创建这样的对象:

public BaseCollection<T> LoadObject<T>(EventHandler handleEvent,
    Func<ServiceContext, T> generator)
{
    var myQuery = generator(MyServiceContext);
    return new DataManager<T>().GetData(myQuery, handleEvent, MyServiceContext);
}

// ...

var obj = LoadObject(handleEvent, Object1.Load);
公共BaseCollection加载对象(EventHandler handleEvent, 函数生成器) { var myQuery=generator(MyServiceContext); 返回新的DataManager().GetData(myQuery、handleEvent、MyServiceContext); } // ... var obj=LoadObject(handleEvent,Object1.Load);
这是假设
myQuery
的类型必须是
T
,不幸的是,问题中的代码没有显示出来。如果它需要是不同的类型,可能是某种类型的
查询
?,那么您需要将
Func
中的
T
(以及
BusinessUtil.Load
的返回类型)也更改为该类型。

您可以使用反射:

public BaseCollection<T> LoadGeneric<T>(EventHandler handleEvent)
{
    var myQuery = (YourQueryType)typeof(T)
        .GetMethod("Load")
        .Invoke(null, new object[] { MyServiceContext });
    return new DataManager<T>().GetData(myQuery , handleEvent, MyServiceContextt);
}
public-BaseCollection-LoadGeneric(EventHandler-handleEvent)
{
var myQuery=(YourQueryType)typeof(T)
.GetMethod(“加载”)
.Invoke(null,新对象[]{MyServiceContext});
返回新的DataManager().GetData(myQuery、handleEvent、MyServiceContext);
}

但我认为重构代码(可能像Timwi建议的那样使用单一静态方法)会是一个更好的选择。

我不明白,你在使用泛型。你能详细说明一下吗?你想完成什么?您希望消除哪些重复?你想让什么代码看起来更干净?@user:你的标题中不需要包含“C”。使用C#标记表示您正在用C#编程。如果你对C#编程语言有疑问,那么在标题中加入C#是合适的。谢谢大家-我知道我已经在使用一些重构,但我想进一步。比如,加载,它将完成我粘贴的所有底层逻辑。我只是觉得代码的复制太多了。@John Saunders:现实点。还有一个“泛型”标签,这是否意味着问题标题不应该包括“泛型”?得了吧。既然你已经把它变成了泛型,我不明白你为什么要用三个不同名称的相同方法。谢谢大家——我知道我已经在使用一些重构了,但我想更进一步。比如,加载,它将完成我粘贴的所有底层逻辑。我只是觉得代码的复制太多了。@Timwi:你说得绝对正确。一开始我没有意识到这些方法中的每一种都是复制方法的一个例子。出于某种原因,我理解这意味着三种方法的组合正在得到复制。谢谢,这看起来很有希望,并将进一步研究。我在上面加了这样一句话:谢谢大家——我知道我已经在使用一些重构了,但我想再进一步。比如,加载,它将完成我粘贴的所有底层逻辑。我只是觉得代码的复制太多了。
public BaseCollection<T> LoadObject<T>(EventHandler handleEvent,
    Func<ServiceContext, T> generator)
{
    var myQuery = generator(MyServiceContext);
    return new DataManager<T>().GetData(myQuery, handleEvent, MyServiceContext);
}

// ...

var obj = LoadObject(handleEvent, Object1.Load);
public BaseCollection<T> LoadGeneric<T>(EventHandler handleEvent)
{
    var myQuery = (YourQueryType)typeof(T)
        .GetMethod("Load")
        .Invoke(null, new object[] { MyServiceContext });
    return new DataManager<T>().GetData(myQuery , handleEvent, MyServiceContextt);
}