using System;
delegate int NumberChanger(int n);
namespace DelegateAppl
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
//create delegate instances
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
//calling the methods using the delegate objects
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
in the above code function called and calling function are in same class.... can we use like both in seperate classes?
if its possible please give an example ......
Surely you can.
Just put your methods in a separate class and create an instance of it to access them:
class Arithmetic
{
int num = 10;
public int AddNum(int p)
{
num += p;
return num;
}
public int MultNum(int q)
{
num *= q;
return num;
}
}
Now call the methods:
class TestDelegate
{
public delegate int NumberChanger(int n);
static void Main(string[] args)
{
//create instance of class
Arithmetic art = new Arithmetic();
//create delegate instances
NumberChanger nc1 = new NumberChanger(art.AddNum); //call with reference
NumberChanger nc2 = new NumberChanger(art.MultNum); //call with reference
//calling the methods using the delegate objects
//add
Console.WriteLine("Value of Num: {0}", nc1(25)); //use it directly because your delegate returns a value
//product
Console.WriteLine("Value of Num: {0}", nc2(5)); //use it directly because your delegate returns a value
Console.ReadKey();
}
}
Note: You don't need getNum() method as you are already returning value from every method and your delegate returns it as well. Also I have removed static from everywhere because it seems you need it.
Related
I am working on a complex project that is related to threading. Here is the simplest interpretation of my problem. Below is the code here are 3 functions excluding the main function. All functions are running in multi-threads. There is a while loop in all functions. I just want to get variable "i" and "k" from "func1" and "func2" respectively and use it in "func3". These variables are updated in the while loop.
This is the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Threading
{
class Program
{
public static void func1() //How can I get the variable "i" from the while loop. Note: This function is running in thread.
{
int i = 1;
while (true)
{
Console.WriteLine("Func1: " + i);
i++;
}
}
public static void func2() //How can I get the variable "k" from the while loop. Note: This function is running in thread.
{
int k = 1;
while (true)
{
Console.WriteLine("Func2: " + k);
k++;
}
}
public static void func3() //After getting variables from func1 and func2 I want them to use in function 3.
{
while (true)
{
int sum = i + k;
Console.WriteLine("the sum is" + sum);
}
}
public static void Main(string[] args)
{
Thread t1 = new Thread(func1);
Thread t2 = new Thread(func2);
Thread t3 = new Thread(func3);
t1.Start();
t2.Start();
t3.Start();
}
}
}
You probably need to hoist the i and k from local variables to private fields of the Program class. Since these two fields will be accessed by more than one threads without synchronization, you should also declare them as volatile:
private static volatile int i = 1;
private static volatile int k = 1;
public static void func1()
{
while (true)
{
Console.WriteLine("Func1: " + i);
i++;
}
}
public static void func2()
{
while (true)
{
Console.WriteLine("Func2: " + k);
k++;
}
}
public static void func3()
{
while (true)
{
int sum = i + k;
Console.WriteLine("the sum is" + sum);
}
}
The pattern of access makes the use of volatile a bit wasteful though. The func1 is the only method that changes the i, so reading it with volatile semantics inside this method is pure overhead. You could use instead the Volatile.Read and Volatile.Write methods for finer control:
private static int i = 1;
private static int k = 1;
public static void func1()
{
while (true)
{
Console.WriteLine("Func1: " + i);
Volatile.Write(ref i, i + 1);
}
}
public static void func2()
{
while (true)
{
Console.WriteLine("Func2: " + k);
Volatile.Write(ref k, k + 1);
}
}
public static void func3()
{
while (true)
{
int sum = Volatile.Read(ref i) + Volatile.Read(ref k);
Console.WriteLine("the sum is" + sum);
}
}
I have two classes, one for defining the algorithm parameters and another to implement the algorithm:
Class 1 (algorithm parameters):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public static class AlgorithmParameters
{
public static int pop_size = 100;
public static double crossover_rate = 0.7;
public static double mutation_rate = 0.001;
public static int chromo_length = 300;
public static int gene_length = 4;
public static int max_allowable_generations = 400;
static Random rand = new Random();
public static double random_num = rand.NextDouble();
}
}
Class 2 (implement algorithm):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public class Program
{
public struct chromo_typ
{
public string bits;
public float fitness;
//public chromo_typ(){
// bits = "";
// fitness = 0.0f;
//}
chromo_typ(string bts, float ftns)
{
bits = bts;
fitness = ftns;
}
};
public static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng =
new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
public string GetRandomBits()
{
string bits="";
for (int i = 0; i < VM_Placement.AlgorithmParameters.chromo_length; i++)
{
if (VM_Placement.AlgorithmParameters.random_num > 0.5f)
bits += "1";
else
bits += "0";
}
return bits;
}
public static void Main(string[] args)
{
Random rnd = new Random(GetRandomSeed());
while (true)
{
chromo_typ[] Population = new chromo_typ[VM_Placement.AlgorithmParameters.pop_size];
double Target;
Console.WriteLine("\n Input a target number");
Target = Convert.ToDouble(Console.ReadLine());
for (int i = 0; i < VM_Placement.AlgorithmParameters.pop_size; i++)
{
Population[i].bits = GetRandomBits();
Population[i].fitness = 0.0f;
}
}
}
}
}
I am getting an error on Population[i].bits = GetRandomBits(); in Main().
Error is:
An object reference is required for the non-static field, method, or property 'VM_Placement.Program.GetRandomBits()'
Am I missing anything?
The Main method is Static. You can not invoke a non-static method from a static method.
GetRandomBits()
is not a static method. Either you have to create an instance of Program
Program p = new Program();
p.GetRandomBits();
or make
GetRandomBits() static.
It looks like you want:
public static string GetRandomBits()
Without static, you would need an object before you can call the GetRandomBits() method. However, since the implementation of GetRandomBits() does not depend on the state of any Program object, it's best to declare it static.
The Main method is static inside the Program class. You can't call an instance method from inside a static method, which is why you're getting the error.
To fix it you just need to make your GetRandomBits() method static as well.
I am preparing for an exam and I have to examine various codes. One is about delegates in C# - I'm failing to see what it does, since I don't know if you can put functions from two different classes in one delegate.
Here's the code:
namespace konzolnaApplikacijaDelegateVoidMain {
public delegate int MyDelegate(int x);
class Program
{
public int number;
public Program (int x)
{
number = x;
}
public int Add(int x)
{
return x + 10;
}
public int Substract(int x)
{
return x - 10;
}
public int Multiply(int x)
{
return x * 2;
}
static void Main(string[] args)
{
MyDelegate delegate;
Program first = new Program(20);
Program second = new Program(50);
delegate = first.Add;
delegate += second.Add;
delegate -= first.Substract;
delegate += second.Multiply;
delegate += first.Add;
delegate(first.number);
delegate(second.number);
Console.Write("{0}", first.number + second.number);
}
}
}
Delegates are quite simple. Consider the following implementation of a delegate.
namespace DelegateExamples
{
class Program
{
//Declare a integer delegate to handle the functions in class A and B
public delegate int MathOps(int a, int b);
static void Main(string[] args)
{
MathOps multiply = ClassA.Multiply;
MathOps add = ClassB.Add;
int resultA = multiply(30, 30);
int resultB = add(1000, 500);
Console.WriteLine("Results: " + resultA + " " + resultB);
Console.ReadKey();
}
}
public class ClassA
{
public static int Multiply(int a, int b)
{
return a * b;
}
}
public class ClassB
{
public static int Add(int a, int b)
{
return a + b;
}
}
}
using System;
namespace _1._75_Using_a_delegate
{
public class Program
{
public delegate int Calculate(int x, int y);
public int Add(int x, int y) { return x + y; }
public int Multiply(int x, int y) { return x * y; }
public void UseDelegate()
{
Calculate calc = Add;
Console.WriteLine(calc(3, 4)); //Displays 7
calc = Multiply;
Console.WriteLine(calc(3, 4));//Displays 12
}
public static void Main()
{
//call and execute UseDelegate()
}
}
}
This should output the above results of 7 and 12.
The delegate function is not directly callable from main in the current state.
Why can't the delegate be seen from main?
Is it necessary to create a class?
How should the delegate function be called?
You cannot call the non-static method from static Method so you have to implement another class like
internal class Check
{
public delegate int Calculate(int x, int y);
public int Add(int x, int y)
{
return x + y;
}
public int Multiply(int x, int y)
{
return x * y;
}
public void UseDelegate()
{
Calculate calc = Add;
Console.WriteLine(calc(3, 4)); //Displays 7
calc = Multiply;
Console.WriteLine(calc(3, 4));//Displays 12
}
}
your call it from your Main Method like
private static void Main(string[] args)
{
new Check().UseDelegate();
}
You don't call the method at all, and you can't now since the Main method is static and your methods are not.
I would recommend to split your code off to a second class, which is easier to call. (Instead of making all methods static)
public class Assignment
{ /* all code except the Main method goes here */ }
Then, in your Main method, instantiate an instance of the Assignment class and call UseDelegate:
public static void Main()
{
Assignment a = new Assignment();
a.UseDelegate();
Console.ReadKey(); // to prevent the console from closing immediate
}
Am studying about delegates. As I read. I learned that adding more than one function in a delegate is called multicast delegate. Based on that I wrote a program. Here two functions (AddNumbers and MultiplyNumbers) I added in the MyDelegate.
Is the below program is an example for multicast delegate ?.
public partial class MainPage : PhoneApplicationPage
{
public delegate void MyDelegate(int a, int b);
// Constructor
public MainPage()
{
InitializeComponent();
MyDelegate myDel = new MyDelegate(AddNumbers);
myDel += new MyDelegate(MultiplyNumbers);
myDel(10, 20);
}
public void AddNumbers(int x, int y)
{
int sum = x + y;
MessageBox.Show(sum.ToString());
}
public void MultiplyNumbers(int x, int y)
{
int mul = x * y;
MessageBox.Show(mul.ToString());
}
}
Yes, it's an example of a multicast delegate. Note that instead of
new MyDelegate(AddNumbers)
you can typically say just
AddNumbers
because a so-called method group conversion exists that will create the delegate instance for you.
Another thing to note is that your declaration public delegate void MyDelegate(int a, int b); does not have to reside inside another type (here inside the MainPage class). It could be a direct member of the namespace (since it's a type). But of course it's perfectly valid to "nest" it inside a class, as you do, for reasons similar to the reason why you create nested classes.
Actually all delegates in C# are MulticastDelegates, even if they only have a single method as target. (Even anonymous functions and lambdas are MulticastDelegates even though they by definition have only single target.)
MulticastDelegate is simply the base class for all kinds of function or method references in C#, whether they contain one or more targets.
So this:
MyDelegate myDel = new MyDelegate(AddNumbers);
Sets myDel to a MulticastDelegate with a single target. But this line:
myDel += new MyDelegate(MultiplyNumbers);
Updates myDel to a MulticastDelegate with two targets.
Multicast delegates is one of the feature of delegates, it wraps the reference of multiple methods and calls it sequentially and it is also known as Delegate Chaining.
Below is the example of multicast delegates.
// Declare Delegates
public delegate void MultiCast(int num1, int num2);
class Program
{
public void Add(int num1, int num2)
{
Console.WriteLine(num1 + num2);
}
public void Sub(int num1, int num2)
{
Console.WriteLine(num1 - num2);
}
public void Mul(int num1, int num2)
{
Console.WriteLine(num1 * num2);
}
static void Main(string[] args)
{
MultiCast del1, del2, del3, multAddDel, multSubDel;
del1 = new Program().Add;
del2 = new Program().Sub;
del3 = new Program().Mul;
//`There are three ways to define the multicast delegate.`
//1 way
//Adding delegates
multAddDel = del1 + del2 + del3;
multAddDel(10, 10);
//Removing Delegates
multSubDel = multAddDel - del3;
multSubDel(10, 10);
Console.WriteLine();
Console.WriteLine("Second Way");
//2 way
MultiCast multAddDel1 = null;
//Adding delegates
multAddDel1 += del1;
multAddDel1 += del2;
multAddDel1 += del3;
multAddDel1(10, 10);
//Removing Delegates
multAddDel1 -= del3;
multAddDel1(10, 10);
Console.WriteLine();
Console.WriteLine("Third Way");
//3 way
MultiCast multAddDel2 = null;
//Adding delegates
multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del1);
multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del2);
multAddDel2 = (MultiCast)Delegate.Combine(multAddDel2, del3);
multAddDel2(10, 10);
//Removing Delegates
multAddDel2 = (MultiCast)
Delegate.Remove(multAddDel2, del3);
multAddDel2(10, 10);
Console.ReadLine();
}
}