查看评论...我希望第二个 MapPost 调用在编译时失败。
我只是在尝试使用 asp.net 最小管道。
我认为这需要受限泛型,但我是 C# 新手,所以认为有人可以快速回答这个问题(希望如此!)。
var router = new ExampleRouter();
var controller = new ExampleWebController();
router.MapPost("/api/ProcessJob", controller.ProcessJob);
// I would like this to be a compile time error, instead of a runtime startup error.
router.MapPost("/api/ProcessJob2", controller.InvalidHandler);
class ExampleWebController {
public ExampleWebController() { }
public void InvalidHandler() { }
public bool ProcessJob(Job job) { return true; }
}
class ExampleRouter {
public ExampleRouter() { }
// TODO: Check at compile that `handler` takes a DTO and returns bool
public void MapPost<TFunc>(string path, TFunc handler) {
var func_type = typeof(TFunc);
// Prints "System.Func" for ProcessJob
// Prints "System.Action" for InvalidHandler
Console.WriteLine(func_type);
var args = func_type.GetGenericArguments();
foreach (Type arg in args) {
// Prints "Job", "System.Boolean" for ProcessJob...awesome
Console.WriteLine(arg);
}
// Construct the DTO dynamically.
// In reality, we'd do this when a http request comes in.
var job_type = args[0];
var job_obj = Activator.CreateInstance(job_type);
DTO dto = (DTO)job_obj;
// Prints "Hello I constructing from test body"
dto.construct_from_body("test body");
}
}
interface DTO {
public void construct_from_body(string body);
}
class Job : DTO
{
public Job() { }
public void construct_from_body(string body)
{
Console.WriteLine($"Hello I constructing from {body}");
}
}
什么是无效的?
你想让编译器每次都失败吗void
处理程序?
实现此目的的一种方法最多有两个参数:
public class MapPostImplementations
{
struct Discard
{
}
public void MapPost<A, B, R>(string path, Func<A, B, R> handler)
{
// Ignore the Discard type arguments
}
public void MapPost<A, R>(string path, Func<A, R> handler)
=> MapPost<A, Discard, R>(path, (a, _) => handler(a));
public void MapPost<R>(string path, Func<R> handler)
=> MapPost<Discard, R>(path, _ => handler());
class ExampleWebController
{
public void InvalidHandler() { }
public bool ProcessNumber(int v) { return true; }
public bool ProcessString(string v) { return true; }
}
ExampleWebController controller = new ExampleWebController();
void Test()
{
MapPost<string, bool>("/api/foo", controller.ProcessString);
MapPost<int, bool>("/api/numberFoo", controller.ProcessNumber);
// does not compile
//MapPost("/api/bar", controller.InvalidHandler);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)