具有多个类约束的C#generics类型
TL; DR
我希望这个用C#编译
public void some_method() where T : class1, class2
这可能吗?
完整的背景
除了一个参数,我有两个相同的方法。
public SignInResponseMessage Generate(SignInRequestMessage request, (X509Certificate2 || WindowsPrincipal) principal, Uri requestUri) { SignInResponseMessage response = null; ClaimsIdentity identity = null; if (principal != null) { identity = CreateSubject(principal); response = Generate(request, requestUri, identity); } else { throw new ArgumentNullException("principal"); } return response; }
我正在复制这种方法,它让我内心畏缩,因为我真的想让这个DRY
。 环顾四周, 这个文档看起来很有希望,但它只允许我添加一个类约束。 我在第二节课上得到以下错误:
错误1类类型约束“class2”必须在任何其他约束之前
如果WindowsPrincipal
和X509Certificate2
是我编写的两个类,我可以很容易地让它们实现相同的接口,我会很高兴,但这不是一个选项。
有没有办法完成我想做的事情?
如果没有, 我想更多地了解使这不可能的潜在机制 。
我担心这可能导致制定实际调用方法的问题。 想象一下,如果其中一个类inheritance自另一个类,并且该方法有一个覆盖!?
有关原因的完整说明,请参阅“钻石问题”
如果你想解决它。 您可以使用适配器设置公共共享接口,然后使用它。
interface IAdaper { SomeMethod(); } class AdapterOne : IAdapter { TypeOneToCall _one; public AdapterOne (TypeOneToCall one) { _one = one; } public SomeMethod() { return _one.SomeMethod(); } } class AdapterTwo : IAdapter { TypeTwoToCall _two; public AdapterTwo (TypeTwoToCall two) { _two = two; } public SomeMethod() { return _two.SomeMethod(); } } class Generic where T : IAdapter { // Your implementation here. }
如果将方法作为参数传递,则T可以是任何值:
public SignInResponseMessage Generate(SignInRequestMessage request, Func createSubject, T principal, Uri requestUri) { SignInResponseMessage response = null; ClaimsIdentity identity = null; if (principal != null) { identity = createSubject(principal); response = Generate(request, requestUri, identity); } else { throw new ArgumentNullException("principal"); } return response; }
所以重用方法:
var r1 = Generate(request, CreateSubject, certificate, uri); var r2 = Generate(request, CreateSubject, principal, uri);