Get interfaces implemented by class
I'm doing assembly analysis project and I encountered a problem.
What I want to achieve is list of all interfaces implemented by a class, but without derived interfaces (and interfaces implemented by derived classes).
Here's an example to illustrate (from LinqPad, .Dump()
is a printing to result window):
void Main()
{
typeof(A).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
}
class C : A {}
class A : IT {}
class B : IT<int> {}
public interface IT : IT <int> {}
public interface IT<T> {}
What I would like to get is
typeof(A).GetInterfaces().Dump(); //typeof(IT)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //
I found this post Type.GetInterfaces() for declared interfaces only with an answer
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
But I'm looking if there is an alternative that iterating through methods.
Is there any way to achieve this?
c# .net reflection .net-assembly
add a comment |
I'm doing assembly analysis project and I encountered a problem.
What I want to achieve is list of all interfaces implemented by a class, but without derived interfaces (and interfaces implemented by derived classes).
Here's an example to illustrate (from LinqPad, .Dump()
is a printing to result window):
void Main()
{
typeof(A).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
}
class C : A {}
class A : IT {}
class B : IT<int> {}
public interface IT : IT <int> {}
public interface IT<T> {}
What I would like to get is
typeof(A).GetInterfaces().Dump(); //typeof(IT)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //
I found this post Type.GetInterfaces() for declared interfaces only with an answer
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
But I'm looking if there is an alternative that iterating through methods.
Is there any way to achieve this?
c# .net reflection .net-assembly
add a comment |
I'm doing assembly analysis project and I encountered a problem.
What I want to achieve is list of all interfaces implemented by a class, but without derived interfaces (and interfaces implemented by derived classes).
Here's an example to illustrate (from LinqPad, .Dump()
is a printing to result window):
void Main()
{
typeof(A).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
}
class C : A {}
class A : IT {}
class B : IT<int> {}
public interface IT : IT <int> {}
public interface IT<T> {}
What I would like to get is
typeof(A).GetInterfaces().Dump(); //typeof(IT)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //
I found this post Type.GetInterfaces() for declared interfaces only with an answer
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
But I'm looking if there is an alternative that iterating through methods.
Is there any way to achieve this?
c# .net reflection .net-assembly
I'm doing assembly analysis project and I encountered a problem.
What I want to achieve is list of all interfaces implemented by a class, but without derived interfaces (and interfaces implemented by derived classes).
Here's an example to illustrate (from LinqPad, .Dump()
is a printing to result window):
void Main()
{
typeof(A).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //typeof(IT), typeof(IT<Int32>)
}
class C : A {}
class A : IT {}
class B : IT<int> {}
public interface IT : IT <int> {}
public interface IT<T> {}
What I would like to get is
typeof(A).GetInterfaces().Dump(); //typeof(IT)
typeof(B).GetInterfaces().Dump(); //typeof(IT<Int32>)
typeof(C).GetInterfaces().Dump(); //
I found this post Type.GetInterfaces() for declared interfaces only with an answer
Type type = typeof(E);
var interfaces = type.GetInterfaces()
.Where(i => type.GetInterfaceMap(i).TargetMethods.Any(m => m.DeclaringType == type))
.ToList();
But I'm looking if there is an alternative that iterating through methods.
Is there any way to achieve this?
c# .net reflection .net-assembly
c# .net reflection .net-assembly
edited Oct 14 '18 at 14:26
Heretic Monkey
6,57063672
6,57063672
asked Oct 11 '18 at 11:17
Łukasz BerwidŁukasz Berwid
1619
1619
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)
public static class InterfaceDumperExtension
{
public static Type DumpInterface(this Type @type)
{
//From your question, I think that you only want to handle
//class case so I am throwing here but you can handle accordingly
if (@type.IsClass == false)
{
throw new NotSupportedException($"{@type} must be a class but it is not!");
}
//All of the interfaces implemented by the class
var allInterfaces = new HashSet<Type>(@type.GetInterfaces());
//Type one step down the hierarchy
var baseType = @type.BaseType;
//If it is not null, it might implement some other interfaces
if (baseType != null)
{
//So let us remove all the interfaces implemented by the base class
allInterfaces.ExceptWith(baseType.GetInterfaces());
}
//NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
//interfaces implemented by those(interfaces of the most derived class)
//We want to remove interfaces that are implemented by other interfaces
//i.e
//public interface A : B{}
//public interface B {}
//public class Top : A{}→ We only want to dump interface A so interface B must be removed
var toRemove = new HashSet<Type>();
//Considering class A given above allInterfaces contain A and B now
foreach (var implementedByMostDerivedClass in allInterfaces)
{
//For interface A this will only contain single element, namely B
//For interface B this will an empty array
foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
{
toRemove.Add(implementedByOtherInterfaces);
}
}
//Finally remove the interfaces that do not belong to the most derived class.
allInterfaces.ExceptWith(toRemove);
//Result
return allInterfaces.ToArray();
}
}
Test code:
public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }
var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52758745%2fget-interfaces-implemented-by-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)
public static class InterfaceDumperExtension
{
public static Type DumpInterface(this Type @type)
{
//From your question, I think that you only want to handle
//class case so I am throwing here but you can handle accordingly
if (@type.IsClass == false)
{
throw new NotSupportedException($"{@type} must be a class but it is not!");
}
//All of the interfaces implemented by the class
var allInterfaces = new HashSet<Type>(@type.GetInterfaces());
//Type one step down the hierarchy
var baseType = @type.BaseType;
//If it is not null, it might implement some other interfaces
if (baseType != null)
{
//So let us remove all the interfaces implemented by the base class
allInterfaces.ExceptWith(baseType.GetInterfaces());
}
//NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
//interfaces implemented by those(interfaces of the most derived class)
//We want to remove interfaces that are implemented by other interfaces
//i.e
//public interface A : B{}
//public interface B {}
//public class Top : A{}→ We only want to dump interface A so interface B must be removed
var toRemove = new HashSet<Type>();
//Considering class A given above allInterfaces contain A and B now
foreach (var implementedByMostDerivedClass in allInterfaces)
{
//For interface A this will only contain single element, namely B
//For interface B this will an empty array
foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
{
toRemove.Add(implementedByOtherInterfaces);
}
}
//Finally remove the interfaces that do not belong to the most derived class.
allInterfaces.ExceptWith(toRemove);
//Result
return allInterfaces.ToArray();
}
}
Test code:
public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }
var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
add a comment |
I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)
public static class InterfaceDumperExtension
{
public static Type DumpInterface(this Type @type)
{
//From your question, I think that you only want to handle
//class case so I am throwing here but you can handle accordingly
if (@type.IsClass == false)
{
throw new NotSupportedException($"{@type} must be a class but it is not!");
}
//All of the interfaces implemented by the class
var allInterfaces = new HashSet<Type>(@type.GetInterfaces());
//Type one step down the hierarchy
var baseType = @type.BaseType;
//If it is not null, it might implement some other interfaces
if (baseType != null)
{
//So let us remove all the interfaces implemented by the base class
allInterfaces.ExceptWith(baseType.GetInterfaces());
}
//NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
//interfaces implemented by those(interfaces of the most derived class)
//We want to remove interfaces that are implemented by other interfaces
//i.e
//public interface A : B{}
//public interface B {}
//public class Top : A{}→ We only want to dump interface A so interface B must be removed
var toRemove = new HashSet<Type>();
//Considering class A given above allInterfaces contain A and B now
foreach (var implementedByMostDerivedClass in allInterfaces)
{
//For interface A this will only contain single element, namely B
//For interface B this will an empty array
foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
{
toRemove.Add(implementedByOtherInterfaces);
}
}
//Finally remove the interfaces that do not belong to the most derived class.
allInterfaces.ExceptWith(toRemove);
//Result
return allInterfaces.ToArray();
}
}
Test code:
public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }
var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
add a comment |
I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)
public static class InterfaceDumperExtension
{
public static Type DumpInterface(this Type @type)
{
//From your question, I think that you only want to handle
//class case so I am throwing here but you can handle accordingly
if (@type.IsClass == false)
{
throw new NotSupportedException($"{@type} must be a class but it is not!");
}
//All of the interfaces implemented by the class
var allInterfaces = new HashSet<Type>(@type.GetInterfaces());
//Type one step down the hierarchy
var baseType = @type.BaseType;
//If it is not null, it might implement some other interfaces
if (baseType != null)
{
//So let us remove all the interfaces implemented by the base class
allInterfaces.ExceptWith(baseType.GetInterfaces());
}
//NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
//interfaces implemented by those(interfaces of the most derived class)
//We want to remove interfaces that are implemented by other interfaces
//i.e
//public interface A : B{}
//public interface B {}
//public class Top : A{}→ We only want to dump interface A so interface B must be removed
var toRemove = new HashSet<Type>();
//Considering class A given above allInterfaces contain A and B now
foreach (var implementedByMostDerivedClass in allInterfaces)
{
//For interface A this will only contain single element, namely B
//For interface B this will an empty array
foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
{
toRemove.Add(implementedByOtherInterfaces);
}
}
//Finally remove the interfaces that do not belong to the most derived class.
allInterfaces.ExceptWith(toRemove);
//Result
return allInterfaces.ToArray();
}
}
Test code:
public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }
var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3
I tried to write my answer as self-documenting as possible.Variables names are also such that they explain what they are doing. So I will let the code do the talking :)
public static class InterfaceDumperExtension
{
public static Type DumpInterface(this Type @type)
{
//From your question, I think that you only want to handle
//class case so I am throwing here but you can handle accordingly
if (@type.IsClass == false)
{
throw new NotSupportedException($"{@type} must be a class but it is not!");
}
//All of the interfaces implemented by the class
var allInterfaces = new HashSet<Type>(@type.GetInterfaces());
//Type one step down the hierarchy
var baseType = @type.BaseType;
//If it is not null, it might implement some other interfaces
if (baseType != null)
{
//So let us remove all the interfaces implemented by the base class
allInterfaces.ExceptWith(baseType.GetInterfaces());
}
//NOTE: allInterfaces now only includes interfaces implemented by the most derived class and
//interfaces implemented by those(interfaces of the most derived class)
//We want to remove interfaces that are implemented by other interfaces
//i.e
//public interface A : B{}
//public interface B {}
//public class Top : A{}→ We only want to dump interface A so interface B must be removed
var toRemove = new HashSet<Type>();
//Considering class A given above allInterfaces contain A and B now
foreach (var implementedByMostDerivedClass in allInterfaces)
{
//For interface A this will only contain single element, namely B
//For interface B this will an empty array
foreach (var implementedByOtherInterfaces in implementedByMostDerivedClass.GetInterfaces())
{
toRemove.Add(implementedByOtherInterfaces);
}
}
//Finally remove the interfaces that do not belong to the most derived class.
allInterfaces.ExceptWith(toRemove);
//Result
return allInterfaces.ToArray();
}
}
Test code:
public interface Interface1 { }
public interface Interface2 { }
public interface Interface3 { }
public interface DerivedInterface1 : Interface1 { }
public interface DerivedInterface2 : Interface2 { }
public class Test : DerivedInterface1, DerivedInterface2, Interface3 { }
var result = typeof(Test).DumpInterface();
//Contains only DerivedInterface1, DerivedInterface2, Interface3
answered Oct 14 '18 at 14:22
Hasan Emrah SüngüHasan Emrah Süngü
1,698422
1,698422
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
add a comment |
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
1
1
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
Well actually that's pretty straight forward and does exactly what i wanted. Thank you!
– Łukasz Berwid
Oct 14 '18 at 19:14
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52758745%2fget-interfaces-implemented-by-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown