Call a function and her params in other params function - c#

I'm trying to do this.
void Test(int num)
{
}
Function(Test(1)); //Error
How write my function to allow this ?
I'm tried this but it doesn't work.
void Function(Action<int> action);
It only work if I don't precise the integer like this.
Function(Test); //Compile but I can't precise the integer
Thank you

How write my function to allow this ?
Change the definition of Function as
void Function(Action action);
Now, you can call it
Function(()=>Test(1))
If you can not change the defintion of Function you can call it as
Function((_)=>Test(1))

This Function(Test(1)); Isn't a valid C# syntax, using () is basically invoking the function, not passing it.
You can only do that when the function is expecting a type, and that function is return it.
Func and Action, Are a pre-defined delegetes that you can use without defining your own.
Like this :
public static void Test(int i)
{
Console.WriteLine("Test()");
}
public static int GetNumber()
{
return 5;
}
Test(GetNumber());
If you want to pass a function to another function, there are numerous ways of doing it, Depends on if the function requires parameters or not, if it has a return type or not.
One parameter and no return type
public static void PrintNumber(int num)
{
Console.WriteLine(num);
}
public static void Function(Action<int> predicate, int param)
{
predicate(param);
}
Function(PrintNumber,5);
One parameter and a return type
public static int Test(int num)
{
return num ;
}
public static void Function(Func<int,int> predicate, int param)
{
predicate(param);
}
Function(Test, 5);
The first int of this Func<int,int> is the parameter type, you have can up to 15 i think plus one which is the last one which is the return type.
From here you can google the rest, Hope this helps :)

Related

how to change library method signature C#

I am consuming some external library that have one method which except parameter as Func type.
class LibClass
{
public void libMethod(Func<int, int, int> add)
{
add(5, 5);
}
}
In my Console app i am consuming like
class Program
{
public static int MyMethod(int a, int b) // want to pass third parameter
{
return 0;
}
static void Main(string[] args)
{
LibClass obj = new LibClass();
obj.libMethod(Program.MyMethod);
Console.Read();
}
}
I want to pass some additional parameter to MyMethod(), but i am not able to pass it. so how can change library method signature?
or how i can pass additional parameter to MyMethod()?
You would have to recompile the library from source in order to change its methods, but I think this might be an XY Problem. You shouldn't need to change the signature to pass another parameter to your method. Example:
int DoSomeMath(int a, int b, int x)
{
return (a + b) * x;
}
If you wanted to have libMethod call DoSomeMath with more parameters, you can just wrap it in a lambda and add your own:
void Main()
{
LibClass obj = new LibClass();
obj.libMethod((a, b) => DoSomeMath(a, b, 42));
Console.Read();
}
The lambda will receive a and b from libMethod, pass those along with 42 to DoSomeMath, and return the return value of DoSomeMath back to libMethod.

How can i call a Func<int,int,int> arguments in a method in C#?

I am trying to create a method which accepts different methods(Funcs) as a parameter.
I have a small problem in defining the Funcs arguments.
Suppose i need to call some thing like this :
public static void SomeTestMethod(int number,string str)
{
Check(MethodOne(number,str));
}
And For Check i have this:
public static int Check(Func<int,string,int> method)
{
// some conditions
method(where should i get the arguments ?);
}
Now my question is how should i set the needed arguments? I feel providing separate arguments for Check, is not elegant, since i need to call Check with the signature i provided in the TestMethod.
I dont want to have
Check(MethodOne,arg1,arg2,etc));
If it is possible i need to provide this signature instead:
Check(MethodOne(number,str));
I think you want this:
public static void SomeTestMethod(int number,string str)
{
Check( () => MethodOne(number,str));
}
public static int Check(Func<int> method)
{
// some conditions
return method();
}
public static void Check<TReturnValue>(
Func<int, string, TReturnValue> method,
int arg1,
string arg2)
{
method(arg1, arg2);
}
calling:
public static SomeClass MethodOne(int p1, string p2)
{
// some body
}
Check(MethodOne, 20, "MyStr");
You have missed the type of return value (the last generic parameter means the type of return value). If you don't want to Func return anything, just use Action:
public static void Check(
Action<int, string> method,
int arg1,
string arg2)
{
method(arg1, arg2);
}

How to get method parameter in an array?

Imagine in a class you got this Method:
float Do(int a_,string b_){}
I'm trying to do something like this:
float Do(int a_, string b_)
{
var params = GetParamsListOfCurrentMethod(); //params is an array that contains (a_ and b_)
}
Can someone help ?
Why should I want to do thet ?
Imagine you got an Interface:
public Interface ITrucMuch
{
float Do(int a_,string b_);
// And much more fct
}
And a lot of classes implementing that interface
And a special class that also implement interface:
public class MasterTrucMuch : ITrucMuch
{
public floatDo(int a_, string b_)
{
ITrucMuch tm = Factory.GetOptimizedTrucMuch(); // This'll return an optimized trucMuch based on some state
if(tm != null)
{
return tm.Do(a_,b_);
}
else
{
logSomeInfo(...);
}
//do the fallback method
}
As the interface constains a lot of method and as the first lien of all method are always the same (checking if there is a better interface that the current instance and if so call the same method on the instance) I try to make a method of it.
Thx
You could do something like this:
var parameters = MethodBase.GetCurrentMethod().GetParameters();
foreach (ParameterInfo parameter in parameters)
{
//..
}
Have a look at the ParameterInfo class.
var params = GetParamsListOfCurrentMethod();
params is a C# keyword so it can't be used as a variable name as above.
Here's a link on how to use the params keyword
http://msdn.microsoft.com/en-us/library/w5zay9db.aspx
And some example code pulled form the article.
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
}
Use Reflection .NET to get the parameter names for the method.
Using reflection to get method name and parameters
or
http://msdn.microsoft.com/en-us/library/system.reflection.parameterinfo.aspx
you can write your function with dynamic parameter like this:
protected void Do(params object[] list)
{
if (list.Length < 2)
return;
int a_=(int)list[0];
string b_=list[1].ToString();
}
I don't get it. If you want the param values, and this is the method you need to work with, what about simple doing
protected void Do(int a_, string b_)
{
var paramValues = new object[]{a_, b_};
}
Do you want a more generic answer? Then you are duplicating questions Can I get parameter names/values procedurally from the currently executing function? and How to get parameter value from StackTrace
And you can't, basically.

Overloading methods in C# .NET

A variable of the type Int32 won't be threated as Int32 if we cast it to "Object" before passing to the overloaded methods below:
public static void MethodName(int a)
{
Console.WriteLine("int");
}
public static void MethodName(object a)
{
Console.ReadLine();
}
To handle it as an Int32 even if it is cast to "Object" can be achieved through reflection:
public static void MethodName(object a)
{
if(a.GetType() == typeof(int))
{
Console.WriteLine("int");
}
else
{
Console.ReadLine();
}
}
Is there another way to do that? Maybe using Generics?
Runtime overload resolution will not be available until C# 4.0, which has dynamic:
public class Bar
{
public void Foo(int x)
{
Console.WriteLine("int");
}
public void Foo(string x)
{
Console.WriteLine("string");
}
public void Foo(object x)
{
Console.WriteLine("dunno");
}
public void DynamicFoo(object x)
{
((dynamic)this).Foo(x);
}
}
object a = 5;
object b = "hi";
object c = 2.1;
Bar bar = new Bar();
bar.DynamicFoo(a);
bar.DynamicFoo(b);
bar.DynamicFoo(c);
Casting this to dynamic enables the dynamic overloading support, so the DynamicFoo wrapper method is able to call the best fitting Foo overload based on the runtime type of the argument.
public static void MethodName(object a)
{
if(a is int)
{
Console.WriteLine("int");
}
else
{
Console.WriteLine("object");
}
}
No, the specific overload of a method that is called is determined at compile-time, not at runtime, unless you're using reflection, thus if you've cast your int to an object, the object overload will be called. I don't believe there's any other way to do this, and generics won't do it for you either.
would this not work?
void MethodName<T>(object a){
T item = a as T;
// treat in the manner you require
}
MethodName<object>(1);
MethodName<Int32>(1);
Perhaps:
public static void MethodName(Type t)
{
Console.WriteLine(t.Name);
}
Then call it:
int a = 0;
string b = "";
object c = new object();
MethodName(a.GetType());
MethodName(b.GetType());
MethodName(c.GetType());
Or:
public static void MethodName<T>(T a)
{
Console.WriteLine(a.GetType().Name);
}
And finally:
public static void MethodName<T>()
{
Console.WriteLine(typeof(T).Name);
}
Update:
It comes down to the fact that the language must somehow be able to determine what type you will be dealing at compile time.
You're pretty much stuck with if/else constructs if you're looking to switch on types. The switch statement itself won't work due to polymorphism. If you're using non-primitive objects, than you can usually accomplish this sort of behavior either with polymorphism or interfaces, such that:
public static void MethodName(MyBaseObject obj)
{
Console.WriteLine(obj.MyVirtualFunctionCall());
}
dynamic overloading was an issue until .NET 3.5, but with .NET 4 its very feasible with few lines of code.
public void publish(dynamic queue)
{
publish(queue);
Console.WriteLine("dynamic queue publishing");
}
public void publish(ValidationQueue queue)
{
Console.WriteLine("Validation queue publishing");
}
how to call
foreach (var queue in _vodaQueueDAO.FetchAllReadyQueuesWithHighestPriority())
{
PublishingService.publish(queue);
}
I wrote an implementation for .NET 3.5 where you e.g. can do something like:
object a = 5;
OverloadResolver.Invoke(MethodName, a);
and it would use the int overload.
Works with compiled and cached Lambda expressions so the performance should be ok.
If anybody needs it, mail me, herzmeisterderwelten, who resides at gmail.com

Why can't I implicitly cast a Delegate with Extension methods?

I'm trying to figure out a way to automatically cast something to an Action or Func and the best I can come up with is something like this:
[TestFixture]
public class ExecutionTest
{
public void BadMethod()
{
throw new Exception("Something bad happened");
}
[Test]
public void TestBadMethod()
{
// Want this, but it won't work!!
// BadMethod.Execute().IgnoreExceptions();
// Ick
((Action)BadMethod).Exec().IgnoreExceptions();
// Still ick
((Action)BadMethod).IgnoreExceptions();
// Do not want
ExtensionMethods.Exec(BadMethod).IgnoreExceptions();
// Better but still meh
this.Exec(BadMethod).IgnoreExceptions();
}
}
public static class ExtensionMethods
{
public static Action Exec(this Action action)
{ return action; }
public static Action Exec(this object obj, Action action)
{ return action; }
public static void IgnoreExceptions(this Action action)
{
try { action(); }
catch {}
}
}
There has to a better/easier way to do this, any thoughts?
In C#, when you use the method name without parenthesis, it's called a method group and it has no representation other than at compile time. A method group can represent more than one method (because of overloads and overrides), therefore to implicitly identify which method is needed, a target delegate type must be provided.
In your case, you are wondering why the extension method parameter type won't trigger the resolution of the function. Simply put, extension are evaluated after the type is known, that is, the this parameter can't be used as an implicit conversion target.
Example of why it would break:
class Test
{
void M (void) // Fits Action delegate
{
}
int M (int) // Fits Func<int,int> delegate
{
return 5;
}
void Test()
{
M.Exec(); // UHOH!!! Which Exec to resolve to ???
}
}
public static class Extensions
{
public static void Exec(this Action action) { }
public static void Exec(this Func<int, int> func) { }
}
As you can see, there is a conflict, but as a matter of fact, the conflict never happens because C# won't even try to find a matching extension with a method group.
Note how this won't work either:
class A
{
public static implicit operator int (A a)
{
return 5;
}
void F()
{
A a = new A();
a.Blah(); // Error! It won't implicitly try C.Blah()
}
}
public static class C
{
public static void Blah (int i)
{
}
}
C# won't match A to C.Blah(int) because it would require an implicit conversion.
As Coincoin says, it's not gonna work well in C# because of the overzealous love for method overloading. The only workaround I've seen people use is to create Action and Func methods:
public Action Action(Action f) { return f; }
public Action<A> Action<A>(Action<A> f) { return f; }
...
public Func<A,B,C,D,E> Func(Func<A,B,C,D,E> f) { return f; }
You could even call them all "F" to get some sort of short syntax:
F(BadMethod).NoExceptions();
You might decide to not define these methods in your class, and put them in a Funcs utility or something. Alias it with F and it doesn't end up too bad:
F.F(BadMethod).NoException();
But overall it still sucks :(.
F# lets you do this kind of thing very naturally by providing a much better type inference system.

Categories

Resources