SPL and PHP allows you to create objects on the fly from classes, that fulfill certain conditions, such as implementing certain interfaces and stuff like that.
However, I would like to do something si开发者_开发技巧milar in c# and automatically create objects from all classes in a namespace and invoke a particular method from those classes that implement a certain interface.
My experience developing desktop apps is very limited. I am not quite sure if I should use delegates to archive this or if reflection is really the way to go.
Well you'll have to use reflection - you may also use delegates, but it's not entirely clear; it will depend on what you're doing.
Assembly.GetTypes()
will return all the types within an assembly; you can use Type.IsAssignableFrom()
to check whether a type implements an interface or derives from another particular type, Type.Namespace
to check the namespace etc. Activator.CreateInstance()
will create an instance of a type by calling the parameterless constructor (if there is one) or you can call a constructor with parameters using other overloads of CreateInstance
or by fetching it first with Type.GetConstructors()
.
If you've tested whether a type implements an interface then after constructing an instance you can cast the reference to that interface, and call the methods within that interface without using any more reflection. If you only know the name of the method at execution time then you'll need to call Type.GetMethod()
to get a MethodInfo
and then Invoke()
to invoke it.
All of this is somewhat error-prone and complicated of course - if you can find any way of staying within static typing, that will make your life easier. What's the bigger picture here? What are you trying to achieve?
I'm not sure why you would want to instantiate an instance of every type in a class but you can use reflection to do it. In addition, it is easier to instantiate of every type in an assembly than it is to do that for every type in a namespace. Anyway, here's a sample of what you might do:
var assembly = Assembly.GetExecutingAssembly(); //here you would retrieve the assembly you wish to search.
foreach ( var type in assembly.GetTypes() )
{
if ( type.GetInterface( "IMyInterface", true ) != null )
{
var instance = Activator.CreateInstance( type ) As IMyInterface;
instance.MethodIWantToCall();
}
}
The following code will Find all the Types that implement IDisposable and are under a certain namespace. If the type is a Form, the ShowDialog method is called.
Type[] types = System.Reflection.Assembly.GetExecutingAssembly().GetTypes();
foreach (Type type in types)
{
if (type.Namespace.Equals("TestApp") &&
(type.GetInterface("System.IDisposable") != null))
{
object obj = Activator.CreateInstance(type);
if (obj is Form)
((Form)obj).ShowDialog();
}
}
精彩评论