I made a very simple program of Delegates. I have no idea why is it showing error, even though I compared it with the one given in MSDN library, its same like the one in MSDN, still not getting compiled..the error says- "The name 'Add' does not exist in the current context "and same for the other method.. Subtract.
Please help me find what is the problem..
namespace DelegatePrac
{
public delegate void One(int a, int b);
public class Some
{
static void Add(int a, int b)
{
int c = a + b; Console.WriteLine("{0}",c);
}
static void Subtract(int a, int b)
{ int c = a - b; Console.WriteLine("{0}",c);
}
}
class Program
{
static void Main(string[] args)
{
One o1,o2;
o1 = Add;//gives error here
o2 = Subtract;//and here!!
o1(33,44);
o2(45, 15);
Console.ReadLine();
}
}
}
I was following this link- http://msdn.microsoft.com/en-us/library/ms173175.aspx
Thanks
You should see a compiler message:
The name 'Add' does not exist in the current context
which tells you that it has no clue which Add method you are talking about; Add is a static method in Some - so you need:
o1 = Some.Add;
o2 = Some.Subtract;
static methods aren't globally available; you can access static methods from the current type (and from base-types) via just their name, but if it is an unrelated type you need to qualify it with the declaring-type.
At this point it will give you a compiler error:
'DelegatePrac.Some.Add(int, int)' is inaccessible due to its protection level
which hints that it is a private method; so add public (or internal) to them:
public static void Add(int a, int b) {...}
Have you tried exchanging those two lines with errors with this?
o1 = Some.Add;
o2 = Some.Subtract;
You haven't posted your error, but the class Program has no Add or Subtract methods, so I guess your error is that Add and Subtract is not found.
EDIT
And as ssd said in his answer, the static methods have to be public to be accessed from outside the class. You have not specified any access modifier, and thereby the methods will default to private.
Two things:
You need to mark Add and Subtract as public.
They are not part of class Program. So while using them in other classes than Some, you need to specify they are part of Some by using Some.Add and Some.Subtract.
Corrected Code:
namespace DelegatePrac
{
public delegate void One(int a, int b);
public class Some
{
public static void Add(int a, int b)
{
int c = a + b; Console.WriteLine("{0}",c);
}
public static void Subtract(int a, int b)
{
int c = a - b; Console.WriteLine("{0}",c);
}
}
class Program
{
static void Main(string[] args)
{
One o1,o2;
o1 = Some.Add;//gives error here
o2 = Some.Subtract;//and here!!
o1(33,44);
o2(45, 15);
Console.ReadLine();
}
}
}
Related
This question already has answers here:
CS0120: An object reference is required for the nonstatic field, method, or property 'foo'
(9 answers)
Closed 10 months ago.
Im trying to call this calculator function:
public static void Main(string[] args) {
int answer = calculate(int a, int b);
Console.WriteLine(answer);
}
public int calculate(int a, int b) {
return a + b;
}
but I keep getting an error about making a non-static reference
The reason you can't call your function is because you can't call a non static function from a static function, try adding the static keyword to your calculate function header
instance member function cannot be called from static function, so you need to make other function static aswell
public static void Main(string[] args) {
int answer = calculate(int a, int b);
Console.WriteLine(answer);
}
public static int calculate(int a, int b) {
return a + b;
}
to call it without making it static you need to create object of the class for example
class Example{
public static void Main(string[] args) {
Example example = new Example();
int answer = example.calculate(int a, int b);
Console.WriteLine(answer);
}
public int calculate(int a, int b) {
return a + b;
}
}
The static keyword means the method does not require an instance of the class in order to be invoked. For example:
MyClass.MyMethod(); // can be called without using the new keyword
Conversely, a non-static method does require an instance of the class in order to be invoked. For example:
var myInstance = new MyClass(); // create instance of class
myInstance.MyMethod(); // then call non-static method
If you think about it for a moment, you can see why a static method cannot call a non-static method. Static methods may be used when the method does not need access to instance level variables or methods. If your static method does need access to the non-static method you have 2 options:
remove the static keyword (EDIT: woops you are calling directly from main so this isn't possible in this case since main must be static. It usually is though)
make the other method static
I work with my first delegate, but i have a little problem, could you help me please.
I work with a consoleApp in dotnet core 3.1
I tried to modify the access identifier with private in public but without result:
using System;
namespace _29_Delegate_Et_Lambda
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Working on Delegate");
Console.WriteLine("-------------------");
double resultatAddition;
resultatAddition = ExecuterOperationDeMath(Additionner, 123, 43);
Console.WriteLine(resultatAddition);
}
public class Calcul
{
// 1- Creation delegate:
delegate double OperationDeMath(double a, double b);
// 2- Declaration methode Additionner du meme type que le delegate.
public static double Additionner(double a, double b) { return a + b; }
// 2- Declaration d'une methode Soustraction du meme type que le delegate.
static double Soustraction(double a, double b) => a + b;
// 3- Utilisation delegate:
static double ExecuterOperationDeMath(OperationDeMath operationAEffectuer, double a, double b)
{
return operationAEffectuer(a, b);
}
}
}
}
There are 2 ways to solve this. But first, make the following chages:
Class Calcul should be public static and should not/need not be nested inside class Program
Make the delegate public to match the accessability of the method
Make Soustraction public static too.
The 2 ways to solve it are either
a. add using static Calcul to the top of your file. This opens up all the static methods of that class with your exact current syntax. or;
b. Use the class name before each call to a static method ie Calcul.ExecuterOperationDeMath
Live examples:
a. https://dotnetfiddle.net/u78cOy
b. https://dotnetfiddle.net/2vRSnm
What exact error do you get? To access a static method you have to specify the class name. And all the relevant methods need to be public in the class.
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Working on Delegate");
Console.WriteLine("-------------------");
double resultatAddition;
resultatAddition = Calcul.ExecuterOperationDeMath(Calcul.Additionner, 123, 43);
Console.WriteLine(resultatAddition);
}
public class Calcul
{
// 1- Creation delegate:
public delegate double OperationDeMath(double a, double b);
// 2- Declaration methode Additionner du meme type que le delegate.
public static double Additionner(double a, double b) { return a + b; }
// 2- Declaration d'une methode Soustraction du meme type que le delegate.
public static double Soustraction(double a, double b) => a + b;
// 3- Utilisation delegate:
public static double ExecuterOperationDeMath(OperationDeMath operationAEffectuer, double a, double b)
{
return operationAEffectuer(a, b);
}
}
}
Demo: https://dotnetfiddle.net/9RUXHc
These problems are about access modifiers, and don't have much, if anything, to do with delegates really.
N.B. As others have mentioned, it's also unclear why the Calcul class is nested within Program. That's relatively unusual and usually unnecessary. But it's not directly relevant to the question you asked.
I have an object that can be of type AudioRequest or VideoRequest. Both classes inherit from Request. I have this class:
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
I want to be able to call DoThings.HandleRequest(r) where r can be either a VideoRequest or AudioRequest and have it call the correct one. Is that possible? I have no control over the *Request classes, so I can't do anything to them. I do have control of the DoThings class and the code that calls HandleRequest. This is the code that calls it, it is WebAPI:
public Response Post(Request input)
{
return DoThings.HandleRequest(input);
}
The code above gives the error Argument 1: cannot convert from 'Request' to 'AudioRequest'.
The original code that I was cleaning up had this:
if (input.GetType() == typeof(AudioRequest))
{
var audioRequest = (AudioRequest)input;
DoThings.HandleRequest(audioRequest);
}
else if (input.GetType() == typeof(VideoRequest))
{
var videoRequest = (VideoRequest)input;
DoThings.HandleRequest(videoRequest);
}
But I figured there was a cleaner way to do this.
Based on the information you've provided so far, your question appears to be a duplicate of How to call a function dynamically based on an object type. I agree with the answer, that the fact that you want to do this suggests you should rethink the design. But, you can use dynamic to accomplish what you want.
Here's a simple console program that demonstrates the basic idea:
class Program
{
static void Main(string[] args)
{
A b = new B(), c = new C();
M(b);
M(c);
}
static void M(A a)
{
WriteLine("M(A)");
M((dynamic)a);
}
static void M(B b)
{
WriteLine("M(B)");
}
static void M(C c)
{
WriteLine("M(C)");
}
}
class A { }
class B : A { }
class C : A { }
The output is:
M(A)
M(B)
M(A)
M(C)
As you can see, in each case the M(A) method is called first, and then the appropriate M(B) or M(C) overload is called from M(A).
In your own example, this could look something like this:
public static DoThings
{
public static void HandleRequest(Request r)
{
// Dynamic dispatch to actual method:
HandleRequest((dynamic)r);
}
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
Note that dynamic does incur a run-time cost, particularly the first time a method is called with a given run-time type. But depending on the frequency and complexity of these "requests", using dynamic could be the cleanest way out of the current situation.
C# will call the appropriate function that matches the arguments and their types.
That being said, both of your functions accept AudioRequest, I believe one of those should accept a VideoRequest.
public static DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(VideoRequest r)
{
// Do things.
}
}
If for some reason you must have two different functions that take only AudioRequest you can differentiate between two function with an extra parameter
public static class DoThings
{
public static void HandleRequest(AudioRequest r)
{
// Do things.
}
public static void HandleRequest(AudioRequest r, bool UseAlternativeMethod)
{
// Do other things.
}
}
Simply having a second parameter will call the second method regardless of it's value.
This isn't a best practices solution as you'd rather discriminate between them by accurately renaming the method name to be accurate but in practice you don't always have a choice.
I have ScriptA with a lot of void functions:
void methodOne() {
some code
}
void methodTwo(int a, int b) {
}
I want to pass to static method of another script. Lets say it scriptB:
ScriptB.staticMethod(methodOne, some, other, primitive, parameters);
ScriptB.staticMethod(methodTwo(a, b), some, other, parameters);
The main Idea of my scripts is that ScriptB will get datas from server and call methods that got from ScriptA to make changes in my game depending on data.
I am not sure what you are trying to achieve here.
But to answer your question, you can pass methods as parameters using delegates. Here is an example:
public class ScriptA
{
public delegate void MethodOneDelegate(int a, int b);
public void MethodOne(int a, int b)
{
Console.WriteLine(a + b);
}
}
public static class ScriptB
{
public static void StaticMethod(ScriptA.MethodOneDelegate function, int a, int b)
{
function(a, b);
}
}
public static void Main()
{
ScriptA scriptA = new ScriptA();
ScriptB.StaticMethod(scriptA.MethodOne, 1, 2);
}
There is alternative solutions, you can take a look at System.Func and System.Action.
Do you need to start the methods when you put them as parameters? Or do you need the values from those methods?
Either way, you could do two things, either try this or just pass the name of the method as string and in your method check which name has been entered and start that method in your method.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C# 4: conflicting overloaded methods with optional parameters
I just have one small research and created next code.
namespace Test {
class Program
{
public interface ITestA
{
void MethodA(int a, int b);
}
public class TestAClass : ITestA
{
public void MethodA(int a, int b)
{
Console.WriteLine("MethodA with param");
}
public void MethodA(int a, int b, bool logic = true)
{
Console.WriteLine("MethodA logic with param");
}
}
public interface ITestB
{
void MethodA(int a, int b, bool logic = true);
}
public class TestBClass : ITestB
{
public void MethodA(int a, int b)
{
Console.WriteLine("MethodB with param");
}
public void MethodA(int a, int b, bool logic = true)
{
Console.WriteLine("MethodB logic with param");
}
}
static void Main(string[] args)
{
var testA = new TestAClass();
testA.MethodA(1, 1);
var testB = new TestBClass();
testB.MethodA(1, 1);
}
} }
I have a question why compiler always choose short method with 2 parameters. And of course all this work by the same way and without Interface.
Thanks
This boils down to how the compiler treats named and optional parameters.
Check out this article at MSDN for more information, especially the paragraph Overload Resolution.
If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.
This is why in your case the compiler chooses the method without any optional parameters.
Because compiler finds a method that correspond perfectly to calling method and use that.
Compiler searches for other suitable methods if first way fails...