C# – Finding controls that use a certain interface in ASP.NET

asp.netc++

Having a heckuva time with this one, though I feel I'm missing something obvious. I have a control that inherits from System.Web.UI.WebControls.Button, and then implements an interface that I have set up. So think…

public class Button : System.Web.UI.WebControls.Button, IMyButtonInterface { ... }

In the codebehind of a page, I'd like to find all instances of this button from the ASPX. Because I don't really know what the type is going to be, just the interface it implements, that's all I have to go on when looping through the control tree. Thing is, I've never had to determine if an object uses an interface versus just testing its type. How can I loop through the control tree and yank anything that implements IMyButtonInterface in a clean way (Linq would be fine)?

Again, know it's something obvious, but just now started using interfaces heavily and I can't seem to focus my Google results enough to figure it out 🙂

Edit: GetType() returns the actual class, but doesn't return the interface, so I can't test on that (e.g., it'd return "MyNamespace.Button" instead of "IMyButtonInterface"). In trying to use "as" or "is" in a recursive function, the type parameter doesn't even get recognized within the function! It's rather bizarre. So

if(ctrl.GetType() == typeToFind) //ok

if(ctrl is typeToFind) //typeToFind isn't recognized! eh?

Definitely scratching my head over this one.

Best Solution

Longhorn213 almost has the right answer, but as as Sean Chambers and bdukes say, you should use

ctrl is IInterfaceToFind

instead of

ctrl.GetType() == aTypeVariable  

The reason why is that if you use .GetType() you will get the true type of an object, not necessarily what it can also be cast to in its inheritance/Interface implementation chain. Also, .GetType() will never return an abstract type/interface since you can't new up an abstract type or interface. GetType() returns concrete types only.

The reason this doesn't work

if(ctrl is typeToFind)  

Is because the type of the variable typeToFind is actually System.RuntimeType, not the type you've set its value to. Example, if you set a string's value to "foo", its type is still string not "foo". I hope that makes sense. It's very easy to get confused when working with types. I'm chronically confused when working with them.

The most import thing to note about longhorn213's answer is that you have to use recursion or you may miss some of the controls on the page.

Although we have a working solution here, I too would love to see if there is a more succinct way to do this with LINQ.