5ea*_*rch 5 c# generics constraints c#-4.0
从我的标题可能有点难以理解我想要实现的目标,所以我会更详细地介绍一下。
我有以下界面:
public interface IModelBuilder<T>
where T : IStandardTemplateTemplate
{
M Build<M>(T pTemplate, params object[] pParams) where M : BaseModel;
}
Run Code Online (Sandbox Code Playgroud)
现在我想在我的实际构建器中实现接口。我用来映射不同对象类型的构建器。所以这看起来如下:
public class BusinessModelBuilder : IModelBuilder<IBusinessTemplate>
{
public virtual M Build<M>(IBusinessTemplate pTemplate, params object[] pParams) where M : BussinessModel
{
var businessModel = Activator.CreateInstance<M>();
// map data
return businessModel;
}
}
Run Code Online (Sandbox Code Playgroud)
现在的问题如下。我无法让约束发挥作用。由于我在接口上定义了约束,它不会让我在实际方法上使用不同的约束,即使我的 BusinessModel 继承自 BaseModel。它一直告诉我我的约束 M 必须匹配来自接口的约束。我尝试了几种不同的方法,但似乎都不起作用。
有谁知道这是否或如何实现?我只想在界面中告诉我的约束,允许继承模型。
这是您的问题的一个简短但完整的示例:
public class Parent { }
public class Child { }
public interface Interface
{
void Foo<T>() where T : Parent;
}
public class Implementation : Interface
{
public void Foo<T>() where T : Child
{
}
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,原因与您的不会编译相同。接口方法的实现必须对泛型参数有完全相同的约束,它不能有更严格的约束。
您的Build方法只能将类型限制为BaseModel,而不是BussinessModel。
如果您更改IModelBuilder接口以添加额外的类级别通用参数,然后将其用作约束,则可以获得所需的功能:
public interface IModelBuilder<T, Model>
where T : IStandardTemplateTemplate
where Model : BaseModel
{
M Build<M>(T pTemplate, params object[] pParams) where M : Model;
}
public class BusinessModelBuilder : IModelBuilder<IBusinessTemplate, BussinessModel>
{
public virtual M Build<M>(IBusinessTemplate pTemplate, params object[] pParams)
where M : BussinessModel
{
var businessModel = Activator.CreateInstance<M>();
// map data
return businessModel;
}
}
Run Code Online (Sandbox Code Playgroud)
该解决方案部分基于Reed 的回答,但更进一步。