I found this code (no conpiler error, it's mean code no error) that is "PingCompletedEventHandler" has constructor like PingCompletedEventHandler(abc) with static void abc(object s, PingCompletedEventArgs e){} right?
static PingCompletedEventHandler Ping_completed(object s, PingCompletedEventArgs e)
{
// This code work fine, it used method void abc below
PingCompletedEventHandler a = new PingCompletedEventHandler(abc);
value.Add("abc");
lock (#lock)
{
instances -= 1;
}
if (e.Reply.Status == IPStatus.Success)
{
string abcd = string.Concat("Active IP: ", e.Reply.Address.ToString());
value.Add("abc");
value.Add(abcd);
result += 1;
}
return a;
}
static void abc(object s, PingCompletedEventArgs e)
{
}
How can they do this. I have tested in my code, it doesn't work. Here is my test:
class Class1
{
static void abcd(int a){
}
public
// Error here: Class1.abcd(int)' is a 'method' but is used like a 'type'
Class1(abcd)
{
}
}
class Class3
{
public static void Main()
{
Class1 asd = new Class1();
}
}
When creating event-handlers you provide a pointer to method within the handlers constructor. This is not "a void", it is a delegate pointing to a method of type void.
The constructor therefor should look similar to:
delegate void HandlerMethod(objects s, PingCompletedEventArgs e);
class PingCompletedEventHandler {
PingCompletedEventHandler(HandlerMethod handler) { ... }
}
Now you can call this constructor with new PingCompletedEventHandler(abc) as abc is a method of type void expecting a param of type objectand of of type PingCompletedEventArgs.
Further reading on delegates here on MSDN
EDIT: Since .NET 3.0 there is also the easier to read Action-type that can be used for methods that do not return anything (void). Thus you may also use PingCompletedEventHandler(Action<object, PingCompletedEventArgs> handler) instead of defining your own delegate.
Further EDIT: To get this to work for your test, your constructor for Class1 should look like this: Class1(Action<int> theAction).
When you want a Function as a Parameter of a Method or a Constructor then you have to use a Delegate
The easiest way is using a Action<...> if you have a Void return type or a Func<T, ...> if you have something else as return type.
In your case it will look like this:
public ClassConstructor(Action<YourParameter> myDelegate)
{
}
For Example:
This is a very simple function and you want to create a delegate of this:
private static int Add(int a, int b)
{
return a + b;
}
then you need a delegate that accepts an int as return type and two ints as parameters.
So you define a Func<...> like this and assign the original method:
Func<int, int, int> addDelegate = Add;
the usage is like using Add only with an other name:
var result = addDelegate(2, 5);
Related
Say I have some external classes that have methods sharing a signature by convention, but that do not implement an interface:
class A {
public string getError();
}
class B {
public string getError();
}
If I want to create a utility function that accepts objects of either type, I could use dynamic:
void printError(dynamic obj) {
Console.WriteLine("Error: {0}", obj.getError());
}
But if I passed a some class C without a getError method, this would be a runtime error. Given that I can't modify A or B (directly), is there a way to implement this so that it would be a compile-time error to pass a type without a getError method, similar to what we'd get with C++ templates?
It sounds like you have an XY Problem. Instead of figuring out how to make your code less type safe, why not just use a overloads and refactor?
public void PrintError(A obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
public void PrintError(B obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
The above code solves your problem, but its no longer DRY. This is where we refactor:
public void PrintError(A obj)
{
PrintError(obj.getError());
}
public void PrintError(B obj)
{
PrintError(obj.getError());
}
//This is private, so you can only call PrintError publicly with an A or B instance
private void PrintError(string error)
{
Console.WriteLine("Error: {0}", error);
//maybe some more logic
}
Now you have type safety, you aren't repeating yourself and you are not "fighting the language" by using it in a way counter to how it was designed.
Use more than one prototype
You can of course define more than one prototype, where each prototype accepts a different class. The compiler will automatically pick the method signature that matches. Example:
public static void PrintError(ExternalClasses.A a)
{
Console.WriteLine(a.getError());
}
public static void PrintError(ExternalClasses.B b)
{
Console.WriteLine(b.getError());
}
Use a single prototype, but with implicit conversion
Another approach would be to define your own class and set up implicit conversion:
public class ErrorContainer
{
protected string _error = null;
public string getError()
{
return _error;
}
public override string ToString()
{
return getError();
}
static public implicit operator ErrorContainer(ExternalClasses.A a)
{
var e = new ErrorContainer();
e._error = a.getError();
return e;
}
static public implicit operator ErrorContainer(ExternalClasses.B b)
{
var e = new ErrorContainer();
e._error = b.getError();
return e;
}
}
Then you can define PrintError to accept an ErrorContainer:
public static void PrintError(ErrorContainer e)
{
Console.WriteLine(e);
}
...which allows you to "pass" either type:
var a = new ExternalClasses.A();
PrintError(a);
var b = new ExternalClasses.B();
PrintError(b);
Under the covers, of course, both A and B are converted to an ErrorContainer.
Example on DotNetFiddle
I'm using the Task class in C# and want to pass a predefined method that returns a value and not using lambdas to the Task.Run method.
Here is a console app with the code:
static int ThreadMethod()
{
return 42;
}
static void Main(string[] args)
{
Task<int> t = Task.Run(function:ThreadMethod);
WriteLine(t.Result);
}
However, it is returning this error:
The call is ambiguous between the following methods or properties: 'Task.Run<TResult>(Func<TResult>)' and 'Task.Run(Func<Task>)'
I tried doing this to fix it and got my expected result:
Task<int> t = Task.Run((Func<int>)ThreadMethod);
However, I am not sure if I'm doing it right or are there any better solution?
Fix your .Run argument like in this example. Can be copied and pasted into LinqPad to test.
public static void Main(string[] args)
{
Task<int> t = Task.Run(() => ThreadMethod());
WriteLine(t.Result);
}
public static int ThreadMethod()
{
return 42;
}
If you want to see it as a variable to pass check out below:
public static void Main(string[] args)
{
//Func<int> is saying I want a function with no parameters
//but returns an int. '() =>' this represents a function with
//no parameters. It then points to your defined method ThreadMethod
//Which fits the notions of no parameters and returning an int.
Func<int> threadMethod = () => ThreadMethod();
Task<int> t = Task.Run(threadMethod);
Console.WriteLine(t.Result);
}
public static int ThreadMethod()
{
return 42;
}
Here is the Documentation on Func(T), on the left hand menu you can select the different variations of Func() objects.
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}
Is there any way so that you can call a function with a variable?
variable+"()";
or something like that, or would I have to use if statements?
A switch seems like it might be the answer, so if the variable's value=var1 I want it to execute var1(); if the value is var2 I want it to execute var2(); how would I code it?
Basically, I am trying to find a cleaner alternative to
if (variable == var1)
{
var1();
}
if (variable == var2)
{
var2();
}
It would be possible to use reflection to find a method in an object and call that method, but the simplest and fastest would be to simply use a switch:
switch (variable) {
case "OneMethod": OneMethod(); break;
case "OtherMethod": OtherMethod(); break;
}
You could use Reflection http://msdn.microsoft.com/en-us/library/ms173183(v=vs.80).aspx to access any function or member by name. It takes some getting used to though. It also has performance issues, so if you can avoid using it, you should.
This is what delegates are for:
Action f = ()=>Console.WriteLine("foo");
f();
I assume using strings is not actually a requirement.
You can use delegates. MSDN: http://msdn.microsoft.com/en-us/library/900fyy8e(v=vs.71).aspx
Exa:
public delegate void TestDelegate();
class TestDelegate
{
public static void Test()
{
Console.WriteLine("In Test");
}
public static void Main()
{
TestDelegate testDelegate = new TestDelegate(Test);
testDelegate();
}
}
You can use the MethodInfo class
Type yourtype = yourObject.GetType();
MethodInfo method = yourtype.GetMethod(variable);
var result = method.Invoke(yourObject,null);
string className = "My.Program.CoolClass"; //including namespace
string method= "Execute";
var type = Type.GetType(className);
var method = type.GetMethod(method);
method.Invoke(classObj, null);
Check out this post.
Use reflection.
http://dotnetslackers.com/Community/blogs/haissam/archive/2007/07/25/Call-a-function-using-Reflection.aspx
You can use MethodMethodInfo.
http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx
http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx
Here's a sample how you can call a method via reflection:
public class MyClass
{
public void PrintHello()
{
Console.WriteLine("Hello World");
}
}
//...
public void InvokeMethod(object obj, string method)
{
// call the method
obj.GetType().GetMethod(method).Invoke(obj, null);
}
//...
var o = new MyClass();
var method = "PrintHello";
//...
InvokeMethod(o, method);
(I will complete #Matthew's excellent answer):
var x = (Action) ( ()=>Print("foo") );
x();
p.s. you can fully variable names too:
private Dictionary<string, dynamic> my = new Dictionary<string, dynamic>();
my["x"] = .....
my["x"]();
public class FunctionTest
{
void Main()
{
Action doSomething;
doSomething = FirstFunction;
doSomething();
doSomething = SecondFunction;
doSomething();
}
void FirstFunction()
{
Console.Write("Hello, ");
}
void SecondFunction()
{
Console.Write("World!\n");
}
}
output:
Hello, World!
Doesn't get too much simpler than that.