How to pass value/parameter into a "public delegate void"? - c#

Please help me with this. Let's say I have this code here...
void IScanSuccessCallback.barcodeDetected(MWResult result)
{
if (result != null)
{
try
{
var scan = Element as BarcodeScannerModal;
if (scan == null)
return;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
}
...and I want that value of MWResult result be passed to this one...
[System.Runtime.InteropServices.ComVisible(true)]
public delegate void EventScanHandler(MWResult result);
I'm really having trouble with this one.

How a basic delegate void is used. A delegate void is a method on where an object or a void is referenced. Its almost like a place holder if you have two of the same function and you need to switch the function, not so much the numbers (swith the + in 5+5 into a *, like 5*5, the example below shows how to do this. It doesent also have to be an int as a return! You can also swith it out for a void in order to do functions). In your case you want to scan the bar-code then check if it is null so I'm confused on why you would want to use a delegate void.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
//delegates are mostly defined outside of the class
public delegate int addn(int num1, int num2);
//the main class
class Program
{
//delegate functions
public static int add1(int num1, int num2)
{
return num1 + num2;
}
public static int add2(int num1, int num2)
{
return num1 * num2;
}
//entry
public static void Main()
{
//here we can reference delegates as a class. its
//called addf in this case.
//first we init add1
addn addf = new addn(add1);
Console.WriteLine(addf(5, 5));
//then we innit add2. note we dont add /*addn*/ in the beginning because
//its already defined
addf = new addn(add2);
Console.WriteLine(addf(5, 5));
//loop
while (true) ;
}
}
}
Unless you are using different versions of IScanSuccessCallback.barcodeDetected I would just call it directly, store the value in a class, then use [System.Runtime.InteropServices.ComVisible(true)]
public delegate void EventScanHandler(Class name result);

A delegate is a type that represents references to methods.
ScanSuccessCallbackImpl t = new ScanSuccessCallbackImpl();
EventScanHandler method = t.barcodeDetected;
method(new MWResult());
Does this answers your question?

Related

Working with methods and return values in classes

Maybe this is a very silly question but it's been a long time I worked with VS.
I'm trying to figure out how I can call a method/function from inside my program e.g. by pressing a button. But the method is written in Class1.cs. I show below what I'm trying but I know this is completely wrong:
namespace TestProject1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
AddingNumbers(3, 5);
label1.Text = Result;
}
}
}
And in Class1.cs I have something like this:
namespace TestProject1
{
class Class1
{
public static AddingNumbers(int num1, int num2)
{
return num1 + num2;
}
}
}
If someone could help me understand this I would really appreciate. I don't need a full answer because then I won't learn anything.
I think it has to do with Public, Static, Void or something like this. I have tried to understand how this principle works by reading on MSDN but I don't grasp it for now.
Advice would be appreciated
I think you have missed return type of AddingNumbers method it would be as follows
public static int AddingNumbers(int num1, int num2)
{
return num1 + num2;
}
And in Form1 class you can called AddingNumbers(static method) by it's class name as follows
private void button1_Click(object sender, EventArgs e)
{
var Result = Class1.AddingNumbers(3, 5);
//As per your requirement you need to show it in label that's
//why used ToString() method to convert from int to string
label1.Text = Result.ToString();
}
Accessing static method within a class still require you to call the full namespace. Therefore you should be calling it using Class1.AddingNumbers(3, 5);
And your static method need a return type int

How to instantiate unique delegates using an anonymous method in a loop (in C#)?

Code:
using System.IO;
using System;
using System.Reflection;
using System.Collections.Generic;
class AnyClass
{
delegate void Del(string str);
static void Main()
{
List<Del> listDel = new List<Del>();
listDel.Add(delegate(string str) { });
Console.WriteLine( listDel[0].Method.ToString() );
listDel.Add(delegate(string str) { });
Console.WriteLine( listDel[1].Method.ToString() );
for (int i = 0; i < 2; i++)
{
listDel.Add(delegate(string str) { });
}
Console.WriteLine( listDel[2].Method.ToString() );
Console.WriteLine( listDel[3].Method.ToString() );
}
}
Output:
Void m__0(System.String)
Void m__1(System.String)
Void m__2(System.String)
Void m__2(System.String)
Why do the delegates instantiated in the loop "point" to the same method (m__2) whereas the ones instantiated outside the loop point to two different methods (m__0 and m__1)?
Is there any way how to instantiate delegates that point to different/unique methods inside a loop?
Example of usage: I need to have delegates as keys in a dictionary, so they need to be unique. Instantiation inside a loop is necessary to provide enough of flexibility.
Why do the delegates instantiated in the loop "point" to the same
method (m__2) whereas the ones instantiated outside the loop point to
two different methods (m__0 and m__1)?
Because behind the scenes the compiler is caching the delegate creation. When you create the first two delegates, the compiler doesn't have knowledge that they are the same, so he creates two different cached delegates and two named methods. Inside your for loop, the compiler is optimizing by only instantiating the delegate once. He can be certain that it's the same delegate each time, instantiate it once, then cache it.
When you de-compile your code, it actually looks like this:
private delegate void Del(string str);
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate3;
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate4;
[CompilerGenerated]
private static Launcher.Del CS$<>9__CachedAnonymousMethodDelegate5;
private static void Main()
{
List<Launcher.Del> listDel = new List<Launcher.Del>();
List<Launcher.Del> arg_24_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate3 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate3 =
new Launcher.Del(Launcher.<Main>b__0);
}
arg_24_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate3);
Console.WriteLine(listDel[0].Method.ToString());
List<Launcher.Del> arg_5D_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate4 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate4 =
new Launcher.Del(Launcher.<Main>b__1);
}
arg_5D_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate4);
Console.WriteLine(listDel[1].Method.ToString());
for (int i = 0; i < 2; i++)
{
List<Launcher.Del> arg_9A_0 = listDel;
if (Launcher.CS$<>9__CachedAnonymousMethodDelegate5 == null)
{
Launcher.CS$<>9__CachedAnonymousMethodDelegate5 =
new Launcher.Del(Launcher.<Main>b__2);
}
arg_9A_0.Add(Launcher.CS$<>9__CachedAnonymousMethodDelegate5);
Console.WriteLine(listDel[2 + i].Method.ToString());
}
}
[CompilerGenerated]
private static void <Main>b__0(string str)
{
}
[CompilerGenerated]
private static void <Main>b__1(string str)
{
}
[CompilerGenerated]
private static void <Main>b__2(string str)
{
}
I would definitely not rely on a delegate being a proper key for a Dictionary.
Is there any way how to instantiate delegates that point to
different/unique methods inside a loop?
You can force the delegate to be a "fresh instance" only by explicitly creating a new Del instance yourself and passing a new named method each time. There are other more "fishy" ways of doing so, but I wouldn't recommend taking those paths just to get a new delegate.
Is there any way how to instantiate delegates that point to different/unique methods inside a loop?
You can't make each loop iteration create a different method because methods are hard-coded into the assembly. Their number is fixed while the loop could be unbounded.
You can make each syntactic appearance of a lambda have a different method by using some kind of hack:
Action<int> x = i => {
if (Environment.CurrentManagedThreadId < 0 /*always false*/)
Console.WriteLine(i + uniqueIntegerHere);
};
This forces each method body to be unique and the compiler cannot ever optimize this away. You can of course pull the body into a helper method.
If you want unique delegates per loop iteration you either need to create methods at runtime or keep a set of statically compiled methods:
void F1() { }
void F2() { }
void F3() { }
...
T4 templates come to mind.
Yet another way similar to the one proposed by #usr. You can force compiler to create a new instance of delegate object using reflection method Delegate.CreateDelegate(type, this, methodInfo). The trick goes at the point where this parameter is always a new object thus forcing myMethod being called on it and thus each delegate actually represents a different context for compiler.
This requires the method for delegation to be inside a separate class, which you can instantiate. I am not sure this requirement fits you actual task. Perhaps you will be inspired for another solution based on this one...
using System.IO;
using System;
using System.Reflection;
using System.Collections.Generic;
class AnyClass
{
delegate void Del(string str);
private static Dictionary<Del, string> dict = new Dictionary<Del, string>();
static void Main()
{
List<Del> listDel = new List<Del>();
int count = 10;
for (int i = 0; i < count; i++)
{
listDel.Add(factory());
dict.Add(listDel[i ], "Delegate " + (i));
}
for (int i = 0; i < count; i++)
{
Console.WriteLine(listDel[i].Method.ToString());
listDel[i].Invoke((i).ToString());
}
Console.ReadLine();
}
public class DelegateEncapsulator
{
private int _number;
public DelegateEncapsulator(int number)
{
_number = number;
}
public void myMethod(string str) {
Console.WriteLine("Delegate " + _number + " " + str);
}
}
private static int delegateCounter = 100;
private static Del factory()
{
var obj = new DelegateEncapsulator(delegateCounter++);
var ret = (Del)Delegate.CreateDelegate(typeof(Del), obj,
typeof(DelegateEncapsulator).GetMethod("myMethod"));
return ret;
}
}
This code adds all delegates into a dictionary. You can play with number elements to be added.
Hope this helps

Why private static method is used when working with Task

This code has been taken from another website :
using System;
using System.Threading.Tasks;
public class Program {
private static Int32 Sum(Int32 n)
{
Int32 sum = 0;
for (; n > 0; n--)
checked { sum += n; }
return sum;
}
public static void Main() {
Task<int32> t = new Task<int32>(n => Sum((Int32)n), 1000);
t.Start();
t.Wait();
// Get the result (the Result property internally calls Wait)
Console.WriteLine("The sum is: " + t.Result); // An Int32 value
}
}
I don't understand the purpose of using the private static method and not any other normal public method.
Thanks
The method is static because it's used from a static context, so it can't be non-static.
The method is probably private because there's no reason to make it public.
This is because you have Main method is static and you can not call non-static method from static method without make object of that class as non-static methods are called with object.
If make the Sum method non-static you will have to call it on object of Program class
private Int32 Sum(Int32 n)
{
//your code
}
Calling will be changed as
Task<Int32> t = new Task<Int32>(n => new Program().Sum((Int32)n), 1000);

trying to write a program to undersatnd pre & post increments and unary operators

using System;
namespace UnaryOperators
{
class UnaryOperators
{
//pre and post incerment checking and examples
public int a=0;
public int PreIncrement()
//shows error here(not all code paths return value)
{
//what i am trying to do here is i want to create 2 methods
//one for pre increment and other for post increment
//but when i am typing program i stuck with above error so
//i didn't complete the code
//i want to know how pre increment and post incerment work
for(a = 0; a < 10; a++)
{
Console.WriteLine("PreIncrement value of a is "+a);
return a;
}
}
public static void Main(string[]args)
{
/*
//if any one gives me a program as an example i will be really thankful
//please give me an example to understand pre and post increments
// if you can understand anything of my code help me solve it
// (but honestly think my code is shit)
*/
}
}
}
This little program shows how pre and post increments works.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("After pre {0}", PreInc());
Console.WriteLine();
Console.WriteLine("After post {0}", PostInc());
Console.ReadLine();
}
public static int PreInc()
{
int a = 0;
do {
Console.WriteLine("PreIncrement value of a is {0}", ++a);
} while (a < 10);
return a;
}
public static int PostInc()
{
int a = 0;
do {
Console.WriteLine("PostIncrement value of a is {0}", a++);
} while (a < 10);
return a;
}
}

C#-Error-does not contain a constructor that takes 1 arguments-I don't get what I am doing wrong?

I keep trying to make this C# program work, but I keep getting an Error about the constructor taking 1 argument. I don't get it. I think it has to do with the " Test myTest = new Test(3);" but I don't know what to do with it.
Any help or steering me in the right direction would be greatly appreciated. Thank you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
public class Test
{
private int tally;
public void Test(int start)
{
tally = start;
}
public void AddFive()
{
tally += 5;
}
public void Display()
{
Console.WriteLine("The tally is {0}", tally);
}
public void Main(string[] args)
{
Test myTest = new Test(3);
myTest.AddFive();
myTest.Display ();
}
}
}
Constructors don't have return type.
So instead of
public void Test(int start)
{
tally = start;
}
you should have
public Test(int start)
{
tally = start;
}
In the constructor definition you said to return void. That is not required. Your constrctor should be
public Test(int strat)
{
...
}

Categories

Resources