我有这样的界面:
public interface IImportModel
{
}
和实现此接口的类:
public class MaterialImportModel: IImportModel
{
public string Name { get; set; }
}
我也有导入处理器的接口:
public interface IImportProcessor<TModel> where TModel: IImportModel
{
void Process(TModel model);
}
该接口的实现之一:
public class MaterialImportProccessor : IImportProcessor<MaterialImportModel>
{
public void Process(MaterialImportModel model)
{
// do some logic here
}
}
现在,我想创建Factory来实例化此类处理器。我有界面:
public interface IImportProcessorFactory
{
IImportProcessor<IImportModel> Get(Parameter parameter);
}
我正在尝试创建实现:
public class ImportProcessorFactory : IImportProcessorFactory
{
public IImportProcessor<IImportModel> Get(Parameter parameter)
{
switch (Parameter)
{
case "Materials":
IImportProcessor<IImportModel> processor = new MaterialImportProccessor();
return processor;
case "Companies":
IImportProcessor<IImportModel> processor = new CompaniesImportProccessor();
return processor;
}
}
}
但我有例外:
错误CS0266无法将类型'MaterialImportProccessor'隐式转换为
IImportProcessor<IImportModel>
。存在显式转换(您是否缺少演员表?)
是正确的。但是我无法使用out
关键字进行IImportProcessor
协方差,因为我使用TModel
作为Process(TModel method)
方法的输入参数。
有什么方法可以重构此代码以使其正常工作?
已编辑
我决定提供有关我打算如何使用该工厂的更多信息。
var deserializer = _deserializerFactory.Get(/*some parameters*/);
var importProcessor = _importProcessorFactory.Get(someEunmValue);
var data = deserializer.Deserialize(file);
importProcessor.Process(data);
因此,我无法使导入处理器出厂通用。
答案 0 :(得分:0)
您应该更改为:
public interface IImportModel
{
}
public class MaterialImportModel: IImportModel
{
public string Name { get; set; }
}
public class CompanieImportModel: IImportModel
{
public int Id { get; set; }
public string Name { get; set; }
}
public interface IImportProcessor
{
void Process(IImportModel model);
}
public class MaterialImportProccessor : IImportProcessor
{
public void Process(IImportModel model)
{
var obj = (MaterialImportModel) model;
// do some logic here
}
}
public interface IImportProcessorFactory
{
IImportProcessor Get();
}
public class ImportProcessorFactory
{
public IImportProcessor Get(Parameter parameter)
{
switch (Parameter)
{
case "Materials":
IImportProcessor processor = new MaterialImportProccessor();
return processor;
case "Companies":
IImportProcessor processor = new CompaniesImportProccessor();
return processor;
}
}
}
答案 1 :(得分:0)
更新
https://dotnetfiddle.net/HYtWiN
考虑为工厂使用dynamic
关键字:
public interface IImportProcessorFactory
{
dynamic Get(Parameter parameter);
}
public class ImportProcessorFactory : IImportProcessorFactory
{
public dynamic Get(Parameter parameter)
{
switch (parameter)
{
case Parameter.Materials:
return new MaterialImportProccessor() ;
case Parameter.Companies:
return new CompaniesImportProccessor();
default:
return null;
}
}
}
因此您可以类似于以下方式使用它:
var factory = new ImportProcessorFactory();
var material = factory.Get(Parameter.Materials);
var company = factory.Get(Parameter.Companies);
var model = new MaterialImportModel();
model.MaterialName = " Metal ";
material.Process(model);
var cModel = new CompanyImportModel();
cModel.CompanyName = "Build Metal Company";
company.Process(cModel);
享受!
答案 2 :(得分:0)
这是我今天能做到的最好的。
public interface IImportProcessor
{
void Process();
}
public class ImportModel1 { public string Name { get; set; }}
public class ImportProcessor1 : IImportProcessor
{
private readonly ImportModel1 data;
public ImportProcessor1(ImportModel1 data) { this.data = data;}
public void Process() => Console.WriteLine($"My name is {data.Name}");
}
public class ImportModel2{ public int Age { get; set; }}
public class ImportProcessor2 : IImportProcessor
{
private readonly ImportModel2 data;
public ImportProcessor2(ImportModel2 data) { this.data = data;}
public void Process() => Console.WriteLine($"My age is {data.Age}");
}
public enum EType {One = 1, Two = 2}
public class ImportProcessorFactory
{
public IImportProcessor Get(EType type, string file)
{
switch (type)
{
case EType.One: return new ImportProcessor1(JsonConvert.DeserializeObject<ImportModel1>(file));
case EType.Two: return new ImportProcessor2(JsonConvert.DeserializeObject<ImportModel2>(file));
}
throw new NotImplementedException("Unable to work with '{type}'");
}
}
class Program
{
public static void Main()
{
var f = new ImportProcessorFactory();
var data1 = (EType.One, "{ Name: 'Vlad' }");
var p1 = f.Get(data1.Item1, data1.Item2 );
Console.WriteLine(p1.GetType());
p1.Process();
var data2 = (EType.Two, "{ Age: '20' }");
var p2 = f.Get(data2.Item1, data2.Item2 );
Console.WriteLine(p2.GetType());
p2.Process();
}
}
ImportProcessor1
My name is Vlad
ImportProcessor2
My age is 20
删除模型接口并使处理器取T
public interface IImportProcessor<T>
{
void Process(T model);
}
使用此设置,所有东西都应该放在一起。
public interface IImportProcessor<T>
{
void Process(T model);
}
public class MaterialImportModel
{
public string Name { get; set; }
}
public class MaterialImportProccessor : IImportProcessor<MaterialImportModel>
{
public void Process(MaterialImportModel model)
{
// do some logic here
}
}
public interface IImportProcessorFactory<T>
{
IImportProcessor<T> Get();
}
public class ImportProcessorFactory : IImportProcessorFactory<MaterialImportModel>
{
public IImportProcessor<MaterialImportModel> Get() => new MaterialImportProccessor();
}
(原答案)
我认为使IImportProcessor
为非通用将使您的模型更加简单,并消除了一整类问题。
public interface IImportProcessor
{
void Process(IImportModel model);
}
物料处理器应实现采用接口而不是具体类的Process
。否则a)不符合合同要求,并且b)放弃了接口的好处:)。
public class MaterialImportProcessor : IImportProcessor
{
public void Process(IImportModel model)
{
// do some logic here
}
}
答案 3 :(得分:0)
我决定添加其他抽象类:
public abstract class ImportProcessor<TModel> : IImportProcessor<MaterialImportModel> where TModel: class
{
public void Process(IImportModel model)
{
Process(model as TModel);
}
public abstract void Process(TModel model);
}
并修改了MaterialImportProccessor
public class MaterialImportProccessor : ImportProcessor<MaterialImportModel>
{
public override void Process(MaterialImportModel model)
{
}
}
答案 4 :(得分:-1)
您是否尝试过使用as运算符添加提到的用户DevFlamur这样的演员?