如何在base class中使用逆变参数?
How to use contravariant parameters in base class?
在 ASP.NET Web API 2.0 项目中,我想使用 HTTP 动词 GET
和 POST
访问来自数据模型的类似对象,它们都实现了界面 ITableRow
。所以我有一个基础 class 提供访问这些模型的默认实现 classes:
class ControllerBase
{
protected string whereAmI = "base controller";
public IHttpActionResult Get(int id)
{
Console.WriteLine(whereAmI + ": GET");
[... here is the default action to get the data object(s) ...]
}
public IHttpActionResult Post([FromBody] ITableRecord value)
{
Console.WriteLine(whereAmI + ": POST " + value.GetType().ToString());
[... here is the default action to create a new data object ...]
}
}
和派生的 class 想要使用 Post()
的 ControllerBase
默认实现:
public class ElementsController : ControllerBase
{
protected string whereAmI = "element controller";
}
使用 GET 路由很容易,但调用 POST 路由时出现问题:
通过Web自动调用API Post的2.0框架现在调用ElementsController.Post()
方法,但不能创建元素对象,因为它只知道它必须构建一个 ITableRecord
对象作为值 - 因为这只是一个接口,所以变量 value
保持 null
.
现在我可以在每个派生的 classes 中写下 Post()
的特定定义,从那里调用 ControllerBase.Post()
:
public override IHttpActionResult Post([FromBody] Element value) // this won't work since the argument types doesn't fit
{
return base.PostHelper(value); // so I have to call a helper function in base
}
我的问题是:是否有更好的(比如:更 DRY)方法来告诉派生的 class Post()
方法的参数必须是哪种特定类型,没有?
这看起来像是仿制药的工作。首先,使你的基础 class 成为泛型,然后将 Post
方法更改为使用泛型类型。例如:
// Note the type constraint too, you may not want this depending on your use case
class ControllerBase<T> where T : ITableRecord
{
public IHttpActionResult Post([FromBody] T value)
{
//...
}
}
现在您的派生控制器将如下所示:
public class ElementsController : ControllerBase<Element>
{
//...
}
在 ASP.NET Web API 2.0 项目中,我想使用 HTTP 动词 GET
和 POST
访问来自数据模型的类似对象,它们都实现了界面 ITableRow
。所以我有一个基础 class 提供访问这些模型的默认实现 classes:
class ControllerBase
{
protected string whereAmI = "base controller";
public IHttpActionResult Get(int id)
{
Console.WriteLine(whereAmI + ": GET");
[... here is the default action to get the data object(s) ...]
}
public IHttpActionResult Post([FromBody] ITableRecord value)
{
Console.WriteLine(whereAmI + ": POST " + value.GetType().ToString());
[... here is the default action to create a new data object ...]
}
}
和派生的 class 想要使用 Post()
的 ControllerBase
默认实现:
public class ElementsController : ControllerBase
{
protected string whereAmI = "element controller";
}
使用 GET 路由很容易,但调用 POST 路由时出现问题:
通过Web自动调用API Post的2.0框架现在调用ElementsController.Post()
方法,但不能创建元素对象,因为它只知道它必须构建一个 ITableRecord
对象作为值 - 因为这只是一个接口,所以变量 value
保持 null
.
现在我可以在每个派生的 classes 中写下 Post()
的特定定义,从那里调用 ControllerBase.Post()
:
public override IHttpActionResult Post([FromBody] Element value) // this won't work since the argument types doesn't fit
{
return base.PostHelper(value); // so I have to call a helper function in base
}
我的问题是:是否有更好的(比如:更 DRY)方法来告诉派生的 class Post()
方法的参数必须是哪种特定类型,没有?
这看起来像是仿制药的工作。首先,使你的基础 class 成为泛型,然后将 Post
方法更改为使用泛型类型。例如:
// Note the type constraint too, you may not want this depending on your use case
class ControllerBase<T> where T : ITableRecord
{
public IHttpActionResult Post([FromBody] T value)
{
//...
}
}
现在您的派生控制器将如下所示:
public class ElementsController : ControllerBase<Element>
{
//...
}