2

I have seen answers on SO with similar questions but did not find one addressing all criteria below.

How can I determine whether class B meets the following criteria when B inherits from A:

  • [B] does not implement any [additional] interfaces (generic or not).
  • [A] implements a generic interface with its own type as the generic parameter?

The following

object o = new SomeObject();
bool result = (o.GetType().GetInterfaces()[0] == typeof(IKnownInterface<???>));
// ??? should be typeof(o). How to achieve this?

I know I can get the interface name string from the type which is something like "NameSpace.ClassName+IKnownInterface'1[[SomeType, ModuleName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" but this does not seem intuitive or safe. Plus the '1 notation is incremental based on the number of generic types used for that interface.

I am either going about this the wrong way or missing something silly here. Please advise.

7
  • 1
    If B inherits from A it's impossible for A to implement an interface and B to not. B, by definition, implements all interfaces A does. Commented May 13, 2013 at 17:51
  • I'll update my question. What I meant was that B does not implement any additional interfaces that A does not have. Commented May 13, 2013 at 17:55
  • Can you explain why you'd want to check your devs like that? Unit tests should point at black boxes, the implementation shouldn't matter. Consider the example of an IEmailer which is internally instantiated from a factory which requires IInstantiable (contrived I know but...). As long as it works as an IEmailer, why do you care what else it is? You're attempting to unit test the implementation not the functionality Commented May 13, 2013 at 19:03
  • @Basic: Unit tests may not be the ideal way to enforce this but it sure is convenient. In my scenario, I have some important classes that have an extremely narrow scope and should not be doing anything besides they are expected to do. In other words, small liberties taken by developers can potentially break the system. This is one of many simple pre-quality-control checks we have for such classes. It makes code logic verification and testing much simpler. Commented May 13, 2013 at 19:07
  • Thanks. Would you mind giving an example of a problem this might avoid? I've never seen a test for this before and would be interested to know. Please feel free not to answer should prefer :) Commented May 13, 2013 at 19:10

2 Answers 2

2

This should do the trick

//get the two types in question
var typeB = b.getType()
var typeA = typeB.BaseType;
var interfaces = typeA.GetInterfaces();

//if the length are different B implements one or more interfaces that A does not
if(typeB.GetInterfaces().length != interfaces.length){
   return false;
} 

//If the list is non-empty at least one implemented interface satisfy the conditions
return (from inter in interfaces
        //should be generic
        where inter.IsGeneric
        let typedef = inter.GetGenericTypeDefinition()
        //The generic type of the interface should be a specific generic type
        where typedef == typeof(IKnownInterface<>) &&
        //Check whether or not the type A is one of the type arguments
              inter.GetGenericTypeArguments.Contains(typeA)).Any()
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. I'm wondering why your code does not need to include the typeof(IKnownInterface<>).MakeGenericType(o.GetType()) method as in @NechytailoOleh's answer.
@RaheelKhan It kind of does. ´let typedef = inter.GetGenericTypeDefinition()` and the following line does the same
Ah I see. I prefer NechytailoOleh's compact comparison but got both points answered here. Thanks again.
@RaheelKhan the compact version only works with one generic type argument. I was under the assumption that it should work with multiple type arguments where one of them should be A
I know and agree. My preference was based solely on the 'Yuckiness' that Query Syntax has for me (even though it is recommended over Method Syntax). Nothing to do with function, just the form. :P
1

try:

 o.GetType().GetInterfaces()[0] == 
                   typeof(IKnownInterface<>).MakeGenericType(o.GetType())

http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx

13 Comments

Hah! First of all, I did not even know you could use an empty <> generic notation. Secondly, wouldn't that mean IKnownInterface<> could be of any generic type? I understand your answer with MakeGenericType but just want to know how to interpret the <> notation. Also, how could I tell if [o] implements any interfaces that its base class does not? Is there some kind of a BindingFlag or would you have to enumerate interfaces for both types and compare?
The typeof(...<>) means any generic variation of IKnownInterface the MakeGeneric specifically returns the correct type for IKnownInterface<"type of o">
@RaheelKhan you do not need to compare interfaces of the two classes. You can just compare the number of interfaces implemented. Since B will have all interfaces from A the only way the length can differ is if B implements some that A does not (see my answer for completeness)
@RuneFS: Thank you! I should have thought of that :).
@Basic: Thank you. That will be valuable.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.