// This method never gets called
public void DoSomethingWithByte(byte b)
{
Writeline(b);
}
class Test<T>
{
public Test(Action<T> act, T data)
{
Dispatcher.Current.BeginInvoke(act, data);
}
}
void TestAll()
{
new Test<Byte>(DoSomethingWithByte, 6);
}
this does not work, why?
It compiles, gets to the line, but does not call the method
Why is this happening?
Act doesn't have a method to call, it is null.
Action<byte> act = ((byte b) DoSomethingwithByte(b));
Then have your method.
public void DoSomethingWithByte(byte b) {}
Related
because of this post I create a new question to make my probleme more clear. I have a class with a next class member, so there will be a daisy chain of class instances. A function in my class calls another member function or all instances in the chain.
c ++ has a resonable solution for this problem. In C# I tried it with a delegate. I made a short program to show what I mean.
class Program {
static void Main(string[] args)
{
DaisyChain TestClass = new DaisyChain(1);
TestClass.AddClass(new DaisyChain(2));
TestClass.AllprintID();
}
}
class DaisyChain {
private int ClassID;
private DaisyChain NextClass;
public DaisyChain(int ID) {ClassID = ID; }
public void AddClass(DaisyChain newClass) {
if (NextClass == null) {
NextClass = newClass;
} else {
NextClass.AddClass(newClass);
}
}
public void AllprintID() {
DoForEach(this.printID);
}
public delegate void doFunc();
public void DoForEach (doFunc aMemberFunc) {
aMemberFunc();
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
public void printID() {
Console.WriteLine(ClassID);
}
};
This example do not work correct, because the class instance is not part of the function call.
I can add a class argumnet to my member function and chang the delegate,
public void printID(DaisyChain me) {
Console.WriteLine(me.ClassID);
}
but then the function will be static and no longer usable in the normal way.
I would be happy if ther another solution.
The delegate type should have an extra argument, since you want to call printID on different objects. You can either add one to doFunc, or just use the built in Action<T> delegate type.
public void DoForEach (Action<DaisyChain> aMemberFunc) {
aMemberFunc(this);
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
When calling DoForEach, you can either pass a lambda expression:
public void AllprintID() {
DoForEach(x => x.printID());
}
Or if you really like the method group syntax for some reason, write a local function printID:
public void AllprintID() {
void PrintID(DaisyChain chain) {
chain.PrintID();
}
DoForEach(PrintID);
}
// method names should start with a capital letter :)
public void PrintID() {
Console.WriteLine(ClassID);
}
Other code can still call PrintID as usual - code outside AllprintID won't even notice the local function.
You are trying to reinvent the wheel. Check LinkedList and LinkedListNode in the documentation. Here is an example to get you on the way:
var daisyChain = new DaisyChain();
daisyChain.Add(1);
daisyChain.Add(2);
class DaisyChain: LinkedList<DaisyChainLink>
{
public void Add(int id) => AddLast(new LinkedListNode<DaisyChainLink>(new DaisyChainLink(id)));
public void Print()
{
var link = this.First;
link?.Value.Print();
while (null != link?.Next)
{
link = link.Next;
link?.Value.Print();
}
}
}
class DaisyChainLink
{
public DaisyChainLink(int id)
{
Id = id;
}
public int Id { get; }
public void Print() => Console.WriteLine(Id);
}
I have a func delegate that is defined as follows,
public enum RunEndStatus
{
Success
}
public class classA
{
Func<object, RunEndStatus> ProcessCalibrationRun { get; set; }
}
Now in an other class lets say classB I am doing something like this,
public class ClassB
{
public void DoSomething()
{
ClassA a = new ClassA();
a.ProcessCalibrationRun = ProcessCalibrationRun;//This is just fine. It won't complain here.
}
public RunEndStatus ProcessCalibrationRun(object obj)
{
//Here I have some piece of code takes so much time. To replicate it,
Thread.Sleep(10000);
}
}
When the DoSomething method is called from somewhere, the application blocks for 10 minutes.So I am trying to fix my problem as follows,
public async Task<RunEndStatus> ProcessCalibrationRun(object obj)
{
await Task.Run(() => { Thread.Sleep(10000)});
return RunEndStatus.Success;
}
I am modifying the call as follows. But it says cannot await method group. Please help how can I await on that method.
public async void DoSomething()
{
ClassA a = new ClassA();
a.ProcessCalibrationRun = await ProcessCalibrationRun; //Here it complains saying cannot await method group.
}
An async signature returns a Task, so your Func will need to as well
public Func<object, Task<RunEndStatus>> ProcessCalibrationRun { get; set; }
Meaning you will not need the async signature in your DoSomething, which should not be async void anyway
public void DoSomething()
{
vara = new ClassA();
a.ProcessCalibrationRun = ProcessCalibrationRun;
}
Then somewhere else (perhaps in ClassA) you can invoke it
public async Task DoSomethingElse()
{
await ProcessCalibrationRun(somethignObject);
}
This is a confusing matter for me, hope to describe it correctly.
This is in a Xamarin.Android project:
I have a class like this (simplified):
public class FinishedListener : Java.Lang.Object, IabHelper.IOnIabSetupFinishedListener
{
public IabResult Data { get; internal set; } = null;
public void OnIabSetupFinished(IabResult res)
{
if (res != null) { Data = res; }
}
}
and a calling method:
public class Class1
{
public void Method1()
{
FinishedListener listner = new FinishedListener();
SomeClass.Init(listner );
// Do something with "listner.Data.Response"
}
}
Because Init class works asynchronously, listner.Data will not be available at once.
What's the best way to implement waiting for this scenario?
I am not sure if your Init method is awaitable, assuming it is you can do something like this;
public async void Method1()
{
FinishedListener listner = new FinishedListener();
await SomeClass.Init(listner);
// Do something with "listner.Data.Response"
}
In case it is non-awaitable do this:
public async void Method1()
{
FinishedListener listner = new FinishedListener();
await Task.Run(()=>{ SomeClass.Init(listner); });
// Do something with "listner.Data.Response"
}
When this executes what will happen is that your existing compiler will wait for execution of await SomeClass.Init(listner); and then the next line shall execute.
I have several methods that execute the same setup code and then some cleanup code. The stuff in between changes. I could do it like this:
void method1()
{
var x = DoSetupStuff();
// Method 1 specific code that uses x
DoCleanupStuff(x);
}
void method2()
{
var x = DoSetupStuff();
// Method 2 specific code that uses x
DoCleanupStuff(x);
}
But I'd rather do something where I don't have to call both setup and cleanup methods every time. Maybe like one call where the method specific stuff can be passed in?
void SetupAndCleanup( method-specific-code )
{
// Setup code here
int x = 1;
// method-specific code injected here.
// note that it uses x.
// cleanup code here
x = 0;
}
The method1, method2 approach works perfectly well, I'm just wandering if there is a way to improve it or make it more elegant.
If "x" is always an int you can just pass in an Action:
void SetupAndCleanup( Action<int> methodCode )
{
// Setup code here
int x = 1;
try
{
methodCode(x);
}
finally
{
// cleanup code here
x = 0;
}
}
You can use a delegate:
void SetupAndCleanup(Action action) {
// setup
action();
// cleanup
}
void Method1() {
SetupAndCleanup(() => {
// do my stuff here
});
}
// or...
private void Method2Impl() {
// do my stuff here
}
void Method2() {
SetupAndCleanup(Method2Impl);
}
or an IDisposable:
private sealed class SetupClass : IDisposable {
public SetupClass() {
// setup
}
public void Dispose() {
// cleanup
}
}
void Method1() {
using (SetupClass setup = new SetupClass() {
// do stuff here
}
}
void Method2() {
using (SetupClass setup = new SetupClass() {
// do stuff here
}
}
If you can place the Method1 & Method2 specific code into their own functions, and each could share the same method signature, then create a delegate type of the signature, and write Method1 & Method2 to conform to the signature and pass it to SetupAndCleanup. A lambda will work if you can do everything you need to using the lambda. To use the lambda just remember that the lambda follows the signature of the delegate.
Sounds like you might want to use a class:
public abstract class DoStuff
{
protected abstract void DoStuffImpl(var x);
private var DoSetupStuff()
{
} // eo DoSetupStuff
private void DoCleanupStuff(var x)
{
} // eo DoCleanupStuff
public DoStuff()
{
} // eo ctor
public void DoMethod()
{
var x = DoSetupStuff();
DoStuffImpl(x);
DoCleanupStuff(x);
} // eo DoMethod
} // eo class DoStuff
Then provide specializations:
public class Special1 : DoStuff
{
protected override DoStuffImpl(var x)
{
// work with x here
}
} // eo class Special1
public class Special2 : DoStuff
{
protected override DoStuffImpl(var x)
{
// work with x here, but in a different way
}
} // eo class Special2
// work with them
Special1 s1; s1.DoMethod();
Special2 s2; s2.DoMethod();
I'd use a method such as this:
void ExecuteMethodWithSetupAndCleanup(Action<int> method)
{
// do the setup stuff
var x = DoSetupStuff();
// run the provided code
method(x);
// do the cleanup stuff
DoCleanupStuff(x);
}
And then use it like this:
void method1()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method1 specific code using x
}
}
void method2()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method2 specific code using x
}
}
Alternatively, if you already have method1() and method2() and you want to keep them separate, and only remove the setup/cleanup from them, you can do something like this:
void method1(int x)
{
// here is the method1 specific code using x
}
void method2(int x)
{
// here is the method2 specific code using x
}
void ExecuteMethod1AndMethod2()
{
ExecuteMethodWithSetupAndCleanup(method1);
ExecuteMethodWithSetupAndCleanup(method2);
}
How about something like:
protected Action DoSetupStuff()
{
//... setup code
Action cleanup = () =>
{
//... prepare cleanup code for later
};
return cleanup;
}
void DoSomethingUseful()
{
var cleanup = DoSetupStuff();
// do something useful
cleanup();
}
This way, your setup method prepares its own cleanup code, and your primary DoSomethingUseful method never has to know about it.
I'm just beginning understanding delegates, I have a class that implemens IDisposable:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
A method (defined in an another class) that is using MyClass:
public class AnotherCLass
{
public static void UseMyClass(MyClass.DoSomething func)
{
using (var mc = new MyClass())
{
// Call the delegate function
mc.func(); // <-------- this is what i should actually call
}
}
}
The actual question: how pass the Zero() function to UseMyClass method? Do I have to create an instance of MyClass (I would like to avoid this...)?
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass(??????????);
}
Is your intent that the instance is provided by the caller of the delegate, and not the creator of the delegate? C# does support such an unbound delegate, it's called an open delegate, and the instance becomes a parameter.
You have to use Delegate.CreateDelegate to create an open delegate, something like this:
public class MyClass : IDisposable
{
public delegate int DoSomething();
public int Zero() {return 0;}
public int One() {return 1;}
public void Dispose()
{
// Cleanup
}
}
public class AnotherCLass
{
public static void UseMyClass(Converter<MyClass,int> func)
{
using (var mc = new MyClass())
{
// Call the delegate function
func(mc);
}
}
}
AnotherClass.UseMyClass(
(Converter<MyClass, int>)Delegate.CreateDelegate(
typeof(Converter<MyClass, int>),
typeof(MyClass).GetMethod("One")
)
);
Of course, you can do it much more easily with a shim:
AnotherClass.UseMyClass( mc => mc.One() ); // C# 3 or later
AnotherClass.UseMyClass( delegate(MyClass mc) { return mc.One(); } ); // C# 2
Because it's an instance method, if you want to call it, you need an instance. That's simply how the CLR works. However, there are two options you could go with:
Make the member functions static. If they're as simple as returning a static value, there's no reason for them to be instance methods. However, if you do actually require instance data...
Use a singleton instance. This way you don't need to create a new instance every time you want to call your static method.
You can do the latter like this:
public class MyClass
{
private static MyClass singletonInstance;
public static MyClass SingletonInstance
{
get
{
if (singletonInstance == null)
{
singletonInstance = new MyClass();
}
return singletonInstance;
}
}
// the rest of your class implementation
}
Then, you can call your static method like so:
AnotherClass.UseMyClass(MyClass.SingletonInstance.Zero);
Cant be done without instantiation. Heres how you can do it:
public static void main(string[] args)
{
// Call AnotherClass method, by passing Zero()
// or One() but without instatiate MyCLass
AnotherClass.UseMyClass((new MyClass()).Zero);
}