Reputation: 345
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
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
Reputation: 23732
Another possibility would be to use inheritance. If the calc
method 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
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
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
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
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