Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here is my implementation:</p> <h3><code>FindAssignableWith</code>, <code>FindBaseClassWith</code> and <code>FindInterfaceWith</code> implementations</h3> <pre><code>// provide common base class or implemented interface public static Type FindAssignableWith(this Type typeLeft, Type typeRight) { if(typeLeft == null || typeRight == null) return null; var commonBaseClass = typeLeft.FindBaseClassWith(typeRight) ?? typeof(object); return commonBaseClass.Equals(typeof(object)) ? typeLeft.FindInterfaceWith(typeRight) : commonBaseClass; } // searching for common base class (either concrete or abstract) public static Type FindBaseClassWith(this Type typeLeft, Type typeRight) { if(typeLeft == null || typeRight == null) return null; return typeLeft .GetClassHierarchy() .Intersect(typeRight.GetClassHierarchy()) .FirstOrDefault(type =&gt; !type.IsInterface); } // searching for common implemented interface // it's possible for one class to implement multiple interfaces, // in this case return first common based interface public static Type FindInterfaceWith(this Type typeLeft, Type typeRight) { if(typeLeft == null || typeRight == null) return null; return typeLeft .GetInterfaceHierarchy() .Intersect(typeRight.GetInterfaceHierarchy()) .FirstOrDefault(); } // iterate on interface hierarhy public static IEnumerable&lt;Type&gt; GetInterfaceHierarchy(this Type type) { if(type.IsInterface) return new [] { type }.AsEnumerable(); return type .GetInterfaces() .OrderByDescending(current =&gt; current.GetInterfaces().Count()) .AsEnumerable(); } // interate on class hierarhy public static IEnumerable&lt;Type&gt; GetClassHierarchy(this Type type) { if(type == null) yield break; Type typeInHierarchy = type; do { yield return typeInHierarchy; typeInHierarchy = typeInHierarchy.BaseType; } while(typeInHierarchy != null &amp;&amp; !typeInHierarchy.IsInterface); } </code></pre> <h3>Remark regarding <code>FindInterfaceWith</code> implementation</h3> <p>Any interfaces that implements either <code>IEnumerable</code> or <code>IEnumerable&lt;T&gt;</code> will be selected before others, what <strong>I considered not to be correct</strong></p> <h3>Open ended question of <code>FindInterfaceWith</code></h3> <p><a href="/questions/tagged/c%23" class="post-tag" title="show questions tagged &#39;c#&#39;" rel="tag">c#</a> allow multiple interfaces to be implemented in one class, in this case first one of interfaces will be returned by <code>FindInterfaceWith</code>, <em>because there is no way how to know which of interfaces <code>IA</code> or <code>IB</code> are preferable in general in following sample</em> </p> <p><img src="https://i.stack.imgur.com/TcqRw.jpg" alt="multiple_interfaces_implementing"></p> <h3>Interfaces and classes hierarchy</h3> <pre><code> public interface IBase {} public interface ISomething {} public interface IDerivied: IBase {} public interface IDeriviedRight: IDerivied {} public interface IDeriviedLeft: IDerivied, IDisposable {} public class AnotherDisposable: IDisposable { public void Dispose() { } } public class DeriviedLeft: IDeriviedLeft { public void Dispose() { } } public class SubDeriviedLeft: DeriviedLeft {} public class SecondSubDeriviedLeft: DeriviedLeft {} public class ThirdSubDeriviedLeft: DeriviedLeft, ISomething {} public class Another {} public class DeriviedRight: IDeriviedRight {} </code></pre> <h3>Test cases</h3> <p>And set of test cases using <code>NUnit</code> assertions:</p> <p><code>FindBaseClassWith</code> assertions example</p> <pre><code>// FindBaseClassWith returns null if one of parameters was an interface. // FindBaseClassWith return null if any of parameter was null. Assert.That(typeof(DeriviedLeft).FindBaseClassWith(typeof(DeriviedLeft)), Is.EqualTo(typeof(DeriviedLeft))); </code></pre> <p><code>FindInterfaceWith</code> assertions example</p> <pre><code>// FindInterfaceWith returns null if they don't have common implemented interface. // FindBaseClassWith return null if any of parameter was null. Assert.That(typeof(DeriviedLeft).FindInterfaceWith(typeof(DeriviedLeft)), Is.EqualTo(typeof(IDeriviedLeft))); </code></pre> <p><code>FinAssignableWith</code> assertions example</p> <pre><code>Assert.That(typeof(DeriviedLeft).FindAssignableWith(typeof(DeriviedLeft)), Is.SameAs(typeof(DeriviedLeft))); </code></pre> <h3>Discussion at CodeReview</h3> <p><a href="https://codereview.stackexchange.com/q/20369/14870">Review of this answer at <code>codereview.stackexchange.com</code></a></p> <p><strong>ps</strong>: <br/> Full sources available [<a href="https://gist.github.com/4442677" rel="nofollow noreferrer">here</a>]</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload