我正在尝试实现通用接口方法,但始终出现错误。我正在粘贴代码以更好地解释我想做什么。
我想要实现的是:基于一些输入数据(SomeModelA,SomeModelB),我想要获得相同的返回类型(模板)。
namespace GenericInterfacePuzzle
{
class Program
{
static void Main(string[] args)
{
var workerA = new WorkerA();
var itemsBasedOnModelA = workerA.Get(new List<SomeModelA>());
var workerB = new WorkerB();
var itemsBasedOnModelB = workerB.Get(new List<SomeModelB>());
}
}
public interface IWorker
{
Template Get<T>(List<T> someModels);
}
public class WorkerA : IWorker
{
public Template Get<SomeModelA>(List<SomeModelA> someModels)
{
ProcessModels(someModels);
return new Template(); // let's say it's based on the result of ProcessModels
}
private void ProcessModels(List<SomeModelA> models)
{
var x = models.First();
}
}
public class WorkerB : IWorker
{
public Template Get<SomeModelB>(List<SomeModelB> someModels)
{
ProcessModels(someModels);
return new Template(); // let's say it's based on the result of ProcessModels
}
private void ProcessModels(List<SomeModelB> models)
{
var x = models.First();
}
}
public class SomeModelA
{
public string Name { get; set; }
}
public class SomeModelB
{
public string Age { get; set; }
}
public class Template
{
// Irrevelant return type
}
}
我想在WorkerA / WorkerB类的级别上知道我正在处理的具体模型,并基于此我想返回一个Template类实例 问题是在调用Process的行中:
ProcessModels(someModels);
我收到一条错误消息:
错误CS1503参数1:无法从SomeModelA的“ System.Collections.Generic.List”转换为GenericInterfacePuzzle.SomeModelA的“ System.Collections.Generic.List”
任何反馈都赞赏这里可能出了什么问题,以及为什么当传递给函数时它不能识别模型类。
克里斯
答案 0 :(得分:3)
1)您需要在接口级别上定义通用参数。否则,编译器将不知道T
参数:
public interface IWorker<T> where T: SomeModel
{
Template Get(List<T> someModels);
}
2)您需要进行约束,因为您可能不希望将任何类型赋予接口。最好为模型创建一个基类,并让它们从中继承:
public abstract class SomeModel { ... }
public class SomeModelA : SomeModel
{
public string Name { get; set; }
}
public class SomeModelB : SomeModel
{
public string Age { get; set; }
}
这样,您可以直接在实现该接口的类的声明中指定模型(请参见第3点)
3)现在,您需要在子类中指定哪个模型属于哪个workertype:
public class WorkerA : IWorker<SomeModelA>
{
public Template Get(List<SomeModelA> someModels)
{
ProcessModels(someModels);
return new Template(); // let's say it's based on the result of ProcessModels
}
private void ProcessModels(List<SomeModelA> models)
{
var x = models.First();
}
}
public class WorkerB : IWorker<SomeModelB>
{
public Template Get(List<SomeModelB> someModels)
{
ProcessModels(someModels);
return new Template(); // let's say it's based on the result of ProcessModels
}
private void ProcessModels(List<SomeModelB> models)
{
var x = models.First();
}
}
您还应该在Get
方法中删除通用规范!
public Template Get<SomeModelA>(List<SomeModelA> someModels)
^
|
remove this
在实现接口时已经指定了以下内容:
public class WorkerA : IWorker<SomeModelA>
4),最后一件事是您在main方法中进行测试:
var worker = new WorkerA();
var itemsBasedOnModelA = worker.Get(new List<SomeModelA>());
var workerB = new WorkerB();
var itemsBasedOnModelB = worker.Get(new List<SomeModelB>());
^
|
this should be [workerB]!