C # typical typing with a few class restrictions

TL DR

I would like this to compile in C #

public void some_method< T >() where T : class1, class2

Is it possible?


Full context

I have two methods that are identical except for parameter one .

 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; } 

I am currently replicating this method and it makes me cringe a bit inside since I really would like to make this DRY -er. Looking around, this documentation seemed promising, but it only allows me to add one class restriction. I get the following error in the second class:

Mistake 1 A class type restriction of 'class2' should appear before any other restrictions

If WindowsPrincipal and X509Certificate2 were the two classes that I wrote, I could easily get them to implement the same interface, and it would be nice to go, but this is not an option.

Is there a way to accomplish what I would like to do?

If not, I would like to know more about the basic mechanism that makes this impossible .

+6
source share
2 answers

I am afraid that this may lead to problems with developing which method to actually invoke. Imagine if one of the specified classes is inherited from the other and there was an override for this method !?

Refer to the Diamond Problem for a full description of the reasons.

If you want to get around this. You can configure a common common interface using the adapter, and then use it.

 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 AdapterOne (TypeTwoToCall two) { _two = two; } public SomeMethod() { return _two.SomeMethod(); } } class Generic<T> where T : IAdapter { // Your implementation here. } 
+6
source

If you pass the method as a parameter, then T can be anything:

  public SignInResponseMessage Generate<T>(SignInRequestMessage request, Func<T, ClaimsIdentity> 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; } 

So, to reuse the method:

  var r1 = Generate<X509Certificate2>(request, CreateSubject, certificate, uri); var r2 = Generate<WindowsPrincipal>(request, CreateSubject, principal, uri); 
+6
source

All Articles