C# 从方法返回更多继承的泛型类?
我有这样的接口:C# 从方法返回更多继承的泛型类?,c#,generics,inheritance,covariance,C#,Generics,Inheritance,Covariance,我有这样的接口: public interface IImportModel { } public class MaterialImportProccessor : IImportProcessor<MaterialImportModel> { public void Process(MaterialImportModel model) { // do some logic here } } 和实现此接口的类: public class M
public interface IImportModel
{
}
public class MaterialImportProccessor : IImportProcessor<MaterialImportModel>
{
public void Process(MaterialImportModel model)
{
// do some logic here
}
}
和实现此接口的类:
public class MaterialImportModel: IImportModel
{
public string Name { get; set; }
}
public interface IImportProcessorFactory
{
IImportProcessor<IImportModel> Get(Parameter parameter);
}
此外,我还为进口处理器提供接口:
public interface IImportProcessor<TModel> where TModel: IImportModel
{
void Process(TModel model);
}
因为它,我不能使进口处理器工厂通用 您是否尝试使用as操作符添加所提到的类似于强制转换的用户DevFlamur?您应该更改为:
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;
}
}
}
更新 考虑为您的工厂使用
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
这是我今天能做的最好的了
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();
}
}
更新1
放下模型接口,让处理器取T
public interface IImportProcessor<T>
{
void Process(T model);
}
材料处理者应实现采用接口而非具体类的
过程
。否则它a)不符合合同,b)您将失去接口的好处:)
我决定添加额外的抽象类:
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);
}
你试过增加演员阵容吗?是的,我试过了。但是在这种情况下有一个运行时错误。因为
IImportProcessor
不是由MaterialImportProcessor
类实现的。是的,但是MaterialImportProcessor实现了IImportProcessor,其中MaterialImportModel实现了IImportModel。如果使用“out”关键字,则可以正常工作。例如:公共接口IImportProcessor,其中TModel:IImportModel;但我不能这样做,因为TModel是'Process()'方法的输入参数。在这种情况下,我必须为每个导入模型实现新的工厂。因为我不仅要导入材料,还要导入公司、用户等。我编辑了我的问题,解释了为什么我不能使用通用工厂。谢谢如果不能使用泛型类,则可以使用泛型方法IImportProcessor Get(),其中TModel:IImportModel
不,我也不能使用泛型方法。因为在我尝试获取导入处理器的步骤中,我不知道在泛型方法中使用它的类型。我只有枚举。我想通过工厂中的枚举获得具体的导入处理器。所以您不应该使用泛型,您可以将接口转换为MaterialImportProcessor中的类。Process Method当我尝试使用'as'运算符时,工厂返回null而不是处理器的实例。当我使用显式转换时,我得到运行时异常。工厂应该返回的不仅仅是MaterialImportProcessor。它应该是通用的。因为我会有很多进口处理器。因此,我不能限制工厂使用MaterialImportModel。谢谢。但我想避免使用仿制药工厂。因为在步骤中,当我尝试获取导入处理器时,我不知道导入模型的具体类型。我只有枚举。工厂应通过此枚举将具体的导入处理器返回给我。我编辑了我的问题,并提供了有关如何使用factory的更多信息。@VladB现在再次检查,我修改了MaterialImportProcessor
类的实现并简化了iThanks。我知道铸造的解决方案。但我想避免这样。如果我找不到更好的解决办法,我将不得不接受。我还需要通用IImportProcessor,因为我计划在DI容器中注册所有导入处理器。因此,它们应该参数化。否则,我只能登记一个。@ VLADB然后考虑使用动态,我更新小提琴URL再次希望它有助于这次:)是的。我同意。如果我无法找到其他解决方案,我将不得不使用这种方法。但在这种情况下,我必须将IImportModel转换为每个处理器中的具体类,这是我想要避免的。我也可以使用justobject。谢谢你的帮助。如果你必须施放,为什么不停止假装这里有接口呢?只要使用具体的类。如果您正在为Name
进行转换,则将其作为模型接口的一部分。我添加接口只是为了编写通用工厂。我想有一个工厂,它将返回具体的进口处理器的一些输入参数。我将有很多模型导入,其中每一个都与具体类型的作品。在工厂里我不能使用混凝土类型。“通用工厂”-通用!=接口。让我们把它变成通用的。
ImportProcessor1
My name is Vlad
ImportProcessor2
My age is 20
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();
}
public interface IImportProcessor
{
void Process(IImportModel model);
}
public class MaterialImportProcessor : IImportProcessor
{
public void Process(IImportModel model)
{
// do some logic here
}
}
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);
}
public class MaterialImportProccessor : ImportProcessor<MaterialImportModel>
{
public override void Process(MaterialImportModel model)
{
}
}