Is there any way to initialise a delegate with a string? I.e. you won't know the name of the function that needs to be called at runtime? Or I'm guessing there is a better way of doing this?
delegate void TestDelegate(myClass obj);
void TestFunction()
{
TestDelegate td = new TestDelegate(myFuncName); // works
TestDelegate td = new TestDelegate("myFuncName"); // doesn't work
}
Update
Is is the code I currently have which is not working
class Program
{
static void Main(string[] args)
{
Bish b = new Bish();
b.MMM();
Console.Read();
}
}
class Bish
{
delegate void TestDelegate();
public void MMM()
{
TestDelegate tDel = (TestDelegate)this.GetType().GetMethod("PrintMe").CreateDelegate(typeof(TestDelegate));
tDel.Invoke();
}
void PrintMe()
{
Console.WriteLine("blah");
}
}
You can create a dynamic delegate this way
class Bish
{
delegate void TestDelegate();
delegate void TestDelegateWithParams(string parm);
public void MMM()
{
TestDelegate tDel = () => { this.GetType().GetMethod("PrintMe").Invoke(this, null); };
tDel.Invoke();
TestDelegateWithParams tDel2 = (param) => { this.GetType().GetMethod("PrintMeWithParams").Invoke(this, new object[] { param }); };
tDel2.Invoke("Test");
}
public void PrintMe()
{
Console.WriteLine("blah");
}
public void PrintMeWithParams(string param)
{
Console.WriteLine(param);
}
}
Related
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
What is the problem in this code?
namespace ConsoleApplication1
{
public delegate void del();
class Program
{
static void Main(string[] args)
{
del d = new del(add);
d += sub;
}
public static void add()
{
Console.WriteLine("add");
}
public static void sub()
{
Console.WriteLine("Sub");
}
}
}
You need to invoke your delegate:
class Program
{
static void Main(string[] args)
{
del d = new del(add);
d += sub;
d.Invoke();
}
public static void add()
{
Console.WriteLine("add");
}
public static void sub()
{
Console.WriteLine("Sub");
}
}
}
So I know how to do:
void PrintFoo () { Console.Write("Foo");}
void DoSomething (Action methodToCall) { methodToCall();}
void Main () { DoSomething(PrintFoo); }
What I want to do:
void PrintFoo (string fooToPrint) { Console.Write(fooToPrint);}
void DoSomething (Action methodToCall) { methodToCall();}
void Main () { DoSomething(PrintFoo("Foo bar baz")); }
Basically call an action WITH Parameters
Use a lambda expression:
void PrintSomething(string stringToPrint) { Console.Write(stringToPrint); }
void DoSomething(Action methodToCall) { methodToCall(); }
void Main()
{
DoSomething(() => PrintSomething("Message"));
}
You may also define actions to require parameter types for the callback.
public void DoSomething(Action<string> Callback){
var result = getMyString();
Callback(result);
}
public void DoSomething(Action<string> CallBack, List<string> Parms){
var sb = new StringBuilder();
Parms.ForEach(p=> sb.Append(Parse(p));
Callback(sb.ToString());
}
I want to wait on the GetValues.Get Method and return the values syncronously to the caller. The ServerDataProvider, BookDataFetcher classes are external to mycode, on which I have no control.
Any help on how to achieve this is much appreciated.
namespace Test {
class Program
{
static void Main(string[] args)
{
GetValues val = new GetValues();
val.Get("BOOKS", DataHandler);
Console.ReadKey();
}
static void DataHandler(IList<string> values) {
}
}
class GetValues
{
public delegate void DataHandler(IList<string> values);
public event DataHandler OnReceiveDataHandler;
public void Get(string colName, DataHandler handler)
{
OnReceiveDataHandler += handler;
GetDataFromServer svr = new GetDataFromServer();
svr.OnReceiveDataHandler += OnReceiveData;
svr.GetData(colName);
}
// Callback Handler
private void OnReceiveData(IList<string> values) {
OnReceiveDataHandler(values);
}
}
class GetDataFromServer
{
internal delegate void DataHandler(IList<string> values);
internal event DataHandler OnReceiveDataHandler;
internal void GetData(string columnName)
{
ServerDataProvider datafetcher = new ServerDataProvider();
datafetcher.OnReceiveDataHandler += OnReceiveData;
Task.Factory.StartNew(() => datafetcher.GetDataFromServer(columnName));
}
// Callback Handler
private void OnReceiveData(IList <string> values) {
OnReceiveDataHandler(values);
}
}
class ServerDataProvider
{
internal delegate void DataHandler(IList<string> values);
internal event DataHandler OnReceiveDataHandler;
public void GetDataFromServer(string columnName)
{
BookDataFetcher b = new BookDataFetcher();
b.OnReceiveDataHandler += OnReceiveData;
Task.Factory.StartNew(() => b.GetBookData(columnName));
}
// Calback Handler
private void OnReceiveData(IList<string> values)
{
OnReceiveDataHandler(values);
}
}
class BookDataFetcher
{
internal delegate void DataHandler(IList<string> values);
internal event DataHandler OnReceiveDataHandler;
public void GetBookData(string col)
{
Thread.Sleep(5000);
OnReceiveDataHandler(new List<string> {"Book1", "Book2"});
}
}
}
What you are asking can be achieved using MethodImplAttribute
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void MethodA()
Having an event like this:
class ABC
{
delegate bool X (int a);
event X eventX;
}
ABC.eventX+=someMethod; //works
I assume the delegate is then created implicitly by compiler?
Yes, prior to .NET 2 you had to manually specify it:
ABC.eventX+=new X(someMethod);
But it is now created implicitly with this syntax:
ABC.eventX+=someMethod;
Yes, it's automatically created.
For example:
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
(new Program()).Entrance();
}
public void Entrance()
{
ABC a = new ABC();
a.eventX += callback;
}
protected bool callback(int a)
{
return true;
}
}
class ABC
{
public delegate bool X(int a);
public event X eventX;
}
}
The Program class will be this if you see in reflector:
internal class Program
{
// Methods
protected bool callback(int a)
{
return true;
}
public void Entrance()
{
ABC a = new ABC();
a.eventX += new ABC.X(this.callback);
}
private static void Main(string[] args)
{
new Program().Entrance();
}
}