How to call a Method from String using c#? [duplicate] - c#

This question already has answers here:
Calling a function from a string in C#
(5 answers)
Closed 1 year ago.
I have created a class library, which has 4 classes each class have 1 method.
First class is the main class for me, in my first class, i have a string called calltoaction, in this string i will be getting the one of below list dynamically
class2.Method2()
class3.Method3()
class4.Method4()
now i want to execute the "class2.method2" from the string "calltoaction".
Say for ex:
class Class1
{
public void method1()
{
string calltoaction = "Class2.Method2()";
}
}
How to execute the "Class2.Method" from the string?

I'm not entirely sure what you are trying to accomplish, but I am sure it can be done in a better way. Basically, if I understand your question correctly, calling this function returns the name of a class and method that you wish to execute.
If that is the case, I would drop the whole "string" thing indefinitely and start looking at delegates.
Consider this:
public class Class2
{
public static void Method2() { }
} // eo class 2
public class Class3
{
public static void Method3() { }
} // eo class 3
public class Class4
{
public static void Method4() { }
} // eo class 4
Now we'd come to our main class
public class MainClass
{
private delegate void MethodDelegate();
private List<MethodDelegate> delegates_ = new List<MethodDelegate>();
// ctor
public MainClass()
{
delegates_.Add(Class2.Method2);
delegates_.Add(Class3.Method3);
delegates_.Add(Class4.Method4);
}
// Call a method
public void Method1()
{
// decide what you want to call:
delegates_[0].Invoke(); // "Class2.Method2"
} // eo Method1
} // eo class Main

Use an Action instead of a string (Assuming you don't need a return value. If you do - use Func):
This is for an idea of how to use it:
public Form1()
{
InitializeComponent();
Action<string> calltoaction;
calltoaction = Doit;
calltoaction("MyText1");
calltoaction = Doit2;
calltoaction("MyText2");
}
void Doit(string s)
{ Text = s; }
void Doit2(string s)
{ textBox1.Text = s; }

I guess a low tech way would be to use a switch statement like so:
using System;
namespace ConsoleApplication24
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Which method would you like to run?");
RunMyMethod(Console.ReadLine());
}
private static void RunMyMethod(string p)
{
switch (p)
{
case "MethodOne();":
MethodOne();
break;
case "MethodTwo();":
MethodTwo();
break;
case "MethodThree();":
MethodThree();
break;
}
}
private static void MethodThree()
{
//Do Stuff
}
private static void MethodTwo()
{
//Do Stuff
}
private static void MethodOne()
{
//Do Stuff
}
}
}

Related

C# | Assigning new class to interface object

Here is the code I currently have, the question follows after:
class Program
{
static void Main(string[] args)
{
var obj1 = new A();
obj1.DoIt();
obj1.SetFlyBehavior(new BehaviorB());
obj1.DoIt();
string input = Console.ReadLine();
}
};
class BaseOfA
{
protected ObjectBehavior behavior;
public void DoIt()
{
behavior.DoIt();
}
public void SetBehavior(ObjectBehavior ob) {
behavior = ob;
}
};
class A : BaseOfA {
public A() {
behavior = new BehaviorA();
}
}
interface ObjectBehavior {
void DoIt();
}
class BehaviorA : ObjectBehavior {
void ObjectBehavior.DoIt() {
Console.WriteLine("Behavior: A");
}
}
class BehaviorB : ObjectBehavior {
void ObjectBehavior.DoIt() {
Console.WriteLine("Behavior: B");
}
}
Now my question is, in this case, how am I going to make it work so that I can assign both BehaviorA and BehaviorB to instance obj1 as long as they implement ObjectBehavior?
You are calling obj.SetFlyBehaviour this method is not defined anywhere. The method you define on BaseOfA is called SetBehaviour. Once that is fixed the code you gave compiles fine for me

How can I make sure that a method of class can be called from a specific class only?

public class A
{
private void MethodA(){}
}
public class B
{
private void MethodB() { }
}
public class C
{
private void MethodC() { }
}
I want to make sure that MethodA can be called only from MethodB. Other method can never call MethodA.
Make MethodA protected and use inheritance like this:
public class A
{
protected void MethodA()
{
}
}
public class B : A
{
private void MethodB()
{
//MethodA is accessible just here
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
But if you don't want to use inheritance and want all the classes in the same assembly you could only nest class B within class A and keep MethodA private. Like this:
public class A
{
private void MethodA()
{
}
public class B
{
private void MethodB()
{
A a = new A();
a.MethodA();
}
}
}
public class C
{
private void MethodC()
{
//MethodA is not accessible here
}
}
public class D : A
{
private void MethodC()
{
//MethodA is not accessible here
}
}
I note that S.Akbari's answer, though good, does not exactly meet your requirement. You said that you wanted MethodA to be callable only within B, but in their answer, MethodA is callable within A.
The solution to the problem you actually posed is to invert the nesting:
class B
{
private class A
{
public void MethodA() { }
}
}
Now MethodA can only be called from within B.
But the question is bizarre. If you have a method that can only be called from B then why is it not a member of B?

Does java support explicit interface implementation like c#? [duplicate]

This question already has answers here:
Is the C# "explicit implementation" of the interface present in Java?
(4 answers)
Closed 9 years ago.
i tried doing this :
interface pet {
void sleep();
}
interface robot {
void sleep();
}
public class roboGarfield implements pet , robot {
/*
* this gives error
void pet.sleep(){
}
*/
#Override
public void sleep() { System.out.println("this isn't really specific.."); }
public static void main(String[] args){
roboGarfield t = new roboGarfield();
t.sleep();
((pet)t).sleep(); // similar to C#
((robot)t).sleep();
}
}
But even though i can cast the roboGarfeild object to its pet or robot type , i cant do an explicit implementation like c#.
Anything i'm doing wrong ? or is it just not supported in java ?
Edit: So , java doesn't support explicit interface implementation like C#. But for cases where they can't be avoided , Holger's delegate method seems like the way out.
Thanks for all the replies.
The standard solution to this kind of problem is to use delegation:
interface pet {
void sleep();
}
interface robot {
void sleep();
}
public class roboGarfield {
private final pet myPetIdentity = new pet() {
public void sleep() { System.out.println("sleeping as pet"); }
public String toString() { return roboGarfield.this.toString(); };
};
private final robot myRobotIdentity = new robot() {
public void sleep() { System.out.println("recharging as robot"); }
public String toString() { return roboGarfield.this.toString(); };
};
public final pet asPet() {
return myPetIdentity;
}
public final robot asRobot() {
return myRobotIdentity;
}
public static void main(String[] args){
roboGarfield t = new roboGarfield();
t.asPet().sleep();
t.asRobot().sleep();
}
}
For bigger methods it’s recommended to let the inner classes delegate back to the outer class to keep the inner classes short. Further, subclasses could override these methods without dealing with the delegation stuff then.
public class roboGarfield {
private final pet myPetIdentity = new pet() {
public void sleep() { petSleep(); }
public String toString() { return roboGarfield.this.toString(); };
};
private final robot myRobotIdentity = new robot() {
public void sleep() { roboSleep(); }
public String toString() { return roboGarfield.this.toString(); };
};
public void roboSleep()
{
System.out.println("recharging as robot");
}
public void petSleep()
{
System.out.println("sleeping as pet");
}
public final pet asPet() {
return myPetIdentity;
}
public final robot asRobot() {
return myRobotIdentity;
}
public static void main(String[] args){
roboGarfield t = new roboGarfield();
t.asPet().sleep();
t.asRobot().sleep();
}
}
Java does not do that.
If two interfaces define methods of identical signature, there is no way to distinguish between them and you can only provide a single implementation that will be used by both.
You have to take care not to end up with interfaces that are incompatible that way.
public class roboGarfield implements pet , robot {
#ovveride
public void sleep(){
//here you are implementing sleep method
//But satisfying both pet and robot interface's sleep method.
}
When you do this , in java the single implementation works for the both interface. AFAIK, NO work around.

Advise on abstraction

I am working on some code whereby I have an abstract class that has a few core properties and a Run(int index) method. I then create new types that inherit this. These new types can have multiple methods that can be called according to the index passed in.
public abstract class BaseClass
{
public abstract void Run(int index);
}
public class Class1 : BaseClass
{
public override void Run(int index)
{
if (index == 0)
{
MethodA();
}
else if (index == 1)
{
MethodB();
}
}
private void MethodA()
{
//do stuff
}
private void MethodB()
{
//do stuff
}
}
I'm just wondering is there a better way to do this. These types and methods would be called from a UI, - a menu click for example. So I might have a class1 and a class2. Class1 might have 3 methods so I could call run(0) ... run(2) on it. Class2 might just have one internal method so I would just call run(0). Maybe I would need to keep a collection of ints with each class I guess as a map to methods. Might also have to add a string to this collection to hold a friendly name for menu items etc..
Can you think of a way to implement this type of mapping while maintaining as much abstraction as possible? Is there a better way to go about this that my current idea?
One way:
You could use an interface instead:
public interface IRunnableSomething {
void Run();
}
public class MyRunnableA :IRunnableSomething
{
public void Run() {
// do stuff
}
}
public class MyRunnableB :IRunnableSomething
{
public void Run() {
// do stuff
}
}
Then in your main class...
public override void Run(IRunnable runnable)
{
runnable.Run();
}
Example of calling it:
myInstanceOfMainClass.Run(new MyRunnableA());
This seems fitting, since you already know what index you were passing in with your original version. This just moves it from int based to interface based (less code too in the end).
Let me explain a bit further so. Here's a slightly more verbose version of what I am trying to do. You can see here that my abstract class has the list of indexes for pointing at the right method in derived classes, and you can see where I am loading types and creating menu items in a UI. I am using this ItemPointer list and passing around ItemPointers to tag properties etc. It all feels a bit wrong somehow.
I wish for the whole thing to be extensible. I might want to add a Class2, Class3 etc all inheriting BaseClass. I might also want to create plugins using BaseClass. Any derived class will have at least one but runable method but will likely have many. So Class1 here is just an example. Does this help explain myself? please go easy on me, I'm learning and that's why I am asking here.
Is what I'm doing here awful? or is it ok? or is there a better way? I guess that's my question. If there is a better way, I'd really appreciate an example. Many thanks to all for the help. It is much appreciated.
public abstract class BaseClass
{
public List<ItemPointer> ItemPointers = new List<ItemPointer>();
public abstract void Run(int index);
}
public class ItemPointer
{
public int Index { get; set; }
public string ClassType { get; set; }
public string UIDescription { get; set; }
}
public class Class1 : BaseClass
{
public Class1()
{
ItemPointers.Add(new ItemPointer { Index = 0, ClassType = this.GetType().Name, UIDescription = "MethodA Description" });
ItemPointers.Add(new ItemPointer { Index = 1, ClassType = this.GetType().Name, UIDescription = "MethodB Description" });
}
public override void Run(int index)
{
if (index == 0)
{
MethodA();
}
else if (index == 1)
{
MethodB();
}
}
private void MethodA()
{
//do stuff
}
private void MethodB()
{
//do stuff
}
}
public class UIForm
{
private List<BaseClass> _baseClasses;
//Formload events load all baseclass types (including plugins via reflection during form init etc. Then call loadUIitems
private void LoadUIItems()
{
foreach (BaseClass bc in _baseClasses)
{
foreach (var p in bc.ItemPointers)
{
ToolStripMenuItem t = new ToolStripMenuItem(p.UIDescription);
t.Click += new EventHandler(WorkerMenu_Click);
t.Tag = p;
actionsToolStripMenuItem.DropDownItems.Add(t);
}
}
}
void WorkerMenu_Click(object sender, EventArgs e)
{
ToolStripMenuItem t = (ToolStripMenuItem)sender;
ItemPointer p = (ItemPointer)t.Tag;
foreach (BaseClass bc in _baseClasses)
{
if (bc.GetType().Name == p.ClassType)
{
bc.Run(p.Index);
}
}
}
}
In your position I might be inclined to try do something like this:
void Main()
{
var a = new Class1();
var b = new Class2();
try
{
a.Run("Foo");
b.Run("Bar", "Yoda");
b.Run("Bat"); // throws exception
}
catch (Exception ex)
{
Console.WriteLine (ex.Message);
}
}
class Base
{
public void Run(string commandName, params object[] args)
{
var method = this.GetType().GetMethod(commandName);
if(method != null)
method.Invoke(this, args);
else
throw new Exception("the command " + commandName + " does not exist on " + this.GetType().Name);
}
}
class Class1 : Base
{
public void Foo()
{
Console.WriteLine ("I am foo");
}
}
class Class2 : Base
{
public void Bar(string str)
{
Console.WriteLine ("I am {0}", str);
}
}
Output:
I am foo
I am Yoda
the command Bat does not exist on Class2

implementing delegates in c#

This would be the first time I'd use delegates in c# so please bear with me. I've read a lot about them but never thought of how/why to use this construct until now.
I have some code that looks like this:
public class DoWork()
{
public MethodWorkA(List<long> TheList) {}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
I call MethodWorkA from a method outside the class and MethodWorkA calls MethodWork 1 and 2. When I call methodA, I'd like to pass some sort of parameter so that sometimes it just does MethodWork1 and sometimes it does both MethodWork1 and MethodWork2.
So when I call the call it looks like this:
DoWork MyClass = new DoWork();
MyClass.MethodA...
Where does the delegate syntax fit in this?
Thanks.
public void MethodWorkA(Action<ParamType1, ParamType2> method) {
method(...);
}
You can call it using method group conversion:
MethodWorkA(someInstance.Method1);
You can also create a multicast delegate that calls two methods:
MethodWorkA(someInstance.Method1 + someInstance.Method2);
For what you described, you don't need delegates.
Just do something like this:
public class DoWork
{
public void MethodWorkA(List<long> theList, bool both)
{
if (both)
{
MethodWork1(1);
MethodWork2(1);
}
else MethodWork1(1);
}
public void MethodWork1(int parameters) { }
public void MethodWork2(int parameters) { }
}
If you're just experimenting with delegates, here goes:
public partial class Form1 : Form
{
Func<string, string> doThis;
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
doThis = do1;
Text = doThis("a");
doThis = do2;
Text = doThis("a");
}
string do1(string s)
{
MessageBox.Show(s);
return "1";
}
string do2(string s)
{
MessageBox.Show(s);
return "2";
}
}
Considering that all methods are inside the same class, and you call MethodWorkA function using an instance of the class, I honestly, don't see any reason in using Action<T> or delegate, as is I understood your question.
When I call methodA, I'd like to pass some sort of parameter so that
sometimes it just does MethodWork1 and sometimes it does both
MethodWork1 and MethodWork2.
Why do not just pass a simple parameter to MethodWorkA, like
public class DoWork()
{
public enum ExecutionSequence {CallMethod1, CallMethod2, CallBoth};
public MethodWorkA(List<long> TheList, ExecutionSequence exec)
{
if(exec == ExecutionSequence.CallMethod1)
MethodWork1(..);
else if(exec == ExecutionSequence.CallMethod2)
MethodWork2(..);
else if(exec == ExecutionSequence.Both)
{
MethodWork1(..);
MethodWork2(..);
}
}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
Much simplier and understandable for your class consumer.
If this is not what you want, please explain.
EDIT
Just to give you an idea what you can do:
Example:
public class Executor {
public void MainMethod(long parameter, IEnumerable<Action> functionsToCall) {
foreach(Action action in functionsToCall) {
action();
}
}
}
and in the code
void Main()
{
Executor exec = new Executor();
exec.MainMethod(10, new List<Action>{()=>{Console.WriteLine("Method1");},
()=>{Console.WriteLine("Method2");}
});
}
The output will be
Method1
Method2
In this way you, for example, can push into the collection only functions you want to execute. Sure, in this case, the decision logic (which functions have to be executed) is determined outside of the call.

Categories

Resources