user2519971
user2519971

Reputation: 345

Passing object of a class as parameter in C#

I want to Passing Class object as parameter in C# like below:

case "Case1":

    class obj1 = new class ();

    string abc = obj1.calc("100");
    break;

case "Case2":

     class2 obj2 = new class2 ();

     string abc = obj2.calc("100");
     break;

so instead of calling obj1.calc and obj2.calc, I want to pass the object obj1 as a method parameter where calculation logic is written.

public static void ProcessModel(object Model)
{
    String abc = <oBJECT>.calc("100");
}

Upvotes: 1

Views: 9002

Answers (6)

Roman
Roman

Reputation: 12171

You should create some interface:

public interface ISomeInterface
{
    string calc(string str);
}

Then implement it by your classes:

public class Class1 : ISomeInterface
{
    //your code
}    

public class Class2 : ISomeInterface
{
    //your code    
}

Then change your method ProcessModel() to:

public static void ProcessModel(ISomeInterface model)
{
    String abc = model.calc("100");
}

OR

If you really don't want to use interfaces for some reason you can use reflection. Your classes should have method with the same names:

public static string CallMethodOfSomeObject(object obj, string methodName, params object[] parameters)
{
    var type = obj.GetType();        
    var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

    //use this if you use C#6 or higher version
    return (string)method?.Invoke(obj, parameters);

    //use this if you use C#5 or lower version
    if (method != null)
    {
        return (string)method.Invoke(obj, parameters);            
    }

    return null;       
}

And your method ProcessModel():

public static void ProcessModel(object model)
{
    String abc = CallMethodOfSomeObject(model, "calc", "100");
}

Also, consider changing ProcessModel() return type to string:

public static string ProcessModel(ISomeInterface model)
{
    return model.calc("100");
}

//OR

public static string ProcessModel(object model)
{
    return CallMethodOfSomeObject(model, "calc", "100");
}

And call this method is every case inside switch:

case "Case1":
    Class1 obj1 = new Class1 ();
    string abc = ProcessModel(obj1);
    break;

case "Case2":
     Class2 obj2 = new Class2 ();
     string abc = ProcessModel(obj2);
     break;

Upvotes: 3

Mong Zhu
Mong Zhu

Reputation: 23732

Another possibility would be to use inheritance. If the calcmethod does the same in both classes class and class2 then you need to implement this method only once in a class from which you inherit the method:

public class C_Parent
{
    public virtual string calc(string s)
    {
        // do what ever you have to
        return "Result of parent";
    }
}

public class C1 : C_Parent
{        
}

public class C2 : C_Parent
{
}

Your ProcessModel method would then take a C_Parent object as parameter and call the method calc:

public static void ProcessModel(C_Parent Model)
{
    String abc = Model.calc("100");
}

If by any chance the second class needs a different implementation you can just override the calc method. This way the ProcessModel method the right implementation will be called:

public class C2 : C_Parent
{
    public override string calc(string s)
    {
        return "Result of C2 child";
    }
}

Upvotes: 0

Ian H.
Ian H.

Reputation: 3919

All the classes that you want to use have to implement an interface. For example like this:

interface ICalculateable
{
    string calc (string value);
}

Then implement these into your classes with ...

class Class1 : ICalculateable

In your method, use the interface as the parameter:

public static string ProcessModel(ICalculateable Model, string value)
{
    return Model.calc(value);
}

Upvotes: 1

Ben
Ben

Reputation: 514

Give your classes an interface such as the example below.

All classes which inherit from IObject must have a calc() method

public class Program
{
    public interface IObject
    {
        float calc();
    }

    public class ObjectA : IObject
    {
        public float calc() { return 5*3;}
    }

    public class ObjectB : IObject
    {
        public float calc() { return 8*7;}
    }

    private static float DoCalc(IObject obj)
    {
        return obj.calc();
    }

    public static void Main(string[] args)
    {
        IObject objA = new ObjectA();
        IObject objB = new ObjectB();

        Console.WriteLine(DoCalc(objA));
        Console.WriteLine(DoCalc(objB));
    }
}

Upvotes: 1

Jcl
Jcl

Reputation: 28272

Just to give another option (which I'd not use unless strictly necessary):

public static void ProcessModel(dynamic Model)
{
  string abc = Model.calc("100");
  // ...
}

This may throw runtime exceptions if the object doesn't have a calc method, and it's definitely slower than using an interface (or reflection if properly cached)... again, I'd not use this, but I'm giving another option.

Upvotes: 0

Dogu Arslan
Dogu Arslan

Reputation: 3384

I will not repeat the Interface answer, it is I think well enough described in answers and comments. One point I would make though is to take the interface dependency in the class constructor rather than directly as a method parameter.

Especially in complex projects, where you have many of these dependencies, I found it much cleaner to have (immutable if possible) classes that take their dependencies through their constructors rather than these dependencies sprinkled through its methods as method parameters. I found it cleaner, more manageable, more deterministic and testable that way. Also better suited for dependency injection and creating your objects in a central object composition root.

Another advantage is better usability, in that the users of your code would not need to constantly pass in interfaces to each one of your methods, they provide the interface(s) once on the object composition to the constructors and then after the use the methods of the composed objects directly with more relevant parameters to the actual problem, without the need of passing in the interfaces.

Upvotes: 0

Related Questions