Oh hi Mark
Oh hi Mark

Reputation: 203

Access many objects with same method within a foreach statement

I have many objects of different type all with the same method .getStatus. I would like to access all the objects' method inside a foreach statement. Example:

String[] names = new String[] {"a", "b", "c"};
foreach (string name in names) {
   dynamic obj = name.getStatus(); //instead of a.getStatus();
   //Do
   //some
   //stuff
   //here
}

Unfortunately the name parameter which is a string does not have a .getStatus option. Any ideas? Is it even possible?

Upvotes: 0

Views: 95

Answers (3)

ofcoursedude
ofcoursedude

Reputation: 456

You mentioned that the objects are fed over WCF so I assume you have the proxy classes for the WCF service generated.

By default, all proxy classes for WCF services are generated as partial and as such you can indeed implement an interface to those classes once they are generated by implementing the interface in another file. You'll have to implement it for each type with an arbitrary method that will then call the type's GetStatus(), but in your foreach loop you'll be able to use the solution by @DrKoch.

(just in case you're not familiar with partial classes [https://msdn.microsoft.com/en-us/library/wa80x488.aspx])

If that doesn't work for you for some reason, you can achieve same results in a similar way by using extension methods, which allows you to "add" a method to a non-static sealed class. Again, you'll have to do this for each type individually, and again it assumes that you know the types in advance and have access to them, e.g. through a referenced assembly or WCF proxy class.

(just in case you're not familiar with extension methods [https://msdn.microsoft.com/en-us/library/bb383977.aspx])

Upvotes: 1

Emmanuel M.
Emmanuel M.

Reputation: 441

You can use Reflection to achieve this (in the case you can't /don't want to use interface)

assuming you have an object Collection 'myObjects' and not only the names

 foreach(object Obj in myObjects)
    {
    //depending on the visibility of your method you may need Bindings flags
    MethodInfo dynMethod = Obj.GetType().GetMethod("getStatus");
    var status = (string)dynMethod.Invoke(Obj, null);
    //with parameters => dynMethod.Invoke(this, new object[] { methodParams });
    }

in the case you just have class/Type names you should probably use something like this (not tested but should works) :

String[] names = new String[] {"a", "b", "c"};
foreach (string name in names) {

    Assembly assembly = Assembly.LoadFile("...Assembly.dll");
    Type type = assembly.GetType(name);//name should be the full type name (Namespace.ClassName)
    //here you get your Object instance
    object Obj= Activator.CreateInstance(type, null);
    MethodInfo dynMethod= Obj.GetType().GetMethod("getStatus");
    var status = (string)dynMethod.Invoke(Obj, null);
}

Upvotes: 0

DrKoch
DrKoch

Reputation: 9772

If all your different objects have the same method getStatus then you should have an Interface IHasGetStatus which contains this method.

All your objects should be declared with and implement this interface.

With this setup, inside your loop, you may cast each object to the IHasGetStatus and acces the method getStatus of this interface. (With the as operator you have smoother error handling)

foreach(object o in myObjects)
{
    IHasGetStatus ihgs = o as IHasGetStatus;
    if(ihgs == null) // error: o has not the required interface
    var status = ihgs.getStatus();
}

Upvotes: 1

Related Questions