How to call method with Func<string, T> as one of parameter - c#

I have a class RemoteData like below,
public class RemoteData
{
public RemoteData(string Message, string IP)
{
this.IP = IP;
this.Message = Message;
}
public string IP;
public string Message;
}
Now I have a IObservable<T> method UdpStream like below,
public static IObservable<RemoteData> UdpStream(IPEndPoint endpoint, Func<string, RemoteData> processor)
{
return Observable.Using(() => new UdpClient(endpoint),
udpClient => Observable.Defer(() =>
udpClient.ReceiveAsync().ToObservable()).Repeat().Select(result => processor(Encoding.UTF8.GetString(result.Buffer))));
}
Now how to call UdpStream, how to pass Func parameter?
var stream = UdpStream(new IPEndPoint(IPAddress.Any, 514), 2nd Param);

Func<T, U> represents a delegate that takes a T parameter and returns U. You can initialize a Func<T, U> using a method reference that matches that signature, or using a lambda expression.
Using a Func<,> as parameter is a common idiom for a callback. For example, if you have a method similar to this:
public static void Method(Func<T, U> func)
{
// ...
}
We can expect that Method will call whaterver you pass in the func parameter. In fact, this happens in the code your present (the parameter Func<string, RemoteData> processor is called where it says processor(Encoding.UTF8.GetString(result.Buffer))).
Now, you have Func<string, RemoteData>, thus you need a method that takes string and returns RemoteData. For example:
public static RemoteData Example(string input)
{
// ...
}
// ...
var observable = UdpStream(endpoint, Example);

Related

Passing parameter to method returning Func

I have the following static class
public static partial class ClassX
{
private static readonly Expression<Func<Customer, CustomerDetail>> _exp = DoX();
private static readonly Func<Customer, CustomerDetail> _comp = DoX().Compile();
static ClassX() { }
public static IQueryable<CustomerDetail> ConvertDetail(this IQueryable<Customer> query)
{
query.Select(_exp);
}
public static CODEDistrictDTO ConvertDetail(this Customer customer)
{
return _comp(customer);
}
private static Expression<Func<CODEDistrictEntity, CODEDistrictDTO>> DoX()
{
}
}
What I need to do is passing a parameter to "DoX" method through the method "ConvertDetail", so the "DoX" method build the logic base on the received parameter
public static partial class ClassX
{
private static readonly Expression<Func<Customer, CustomerDetail>> _exp = DoX(); //problem
private static readonly Func<Customer, CustomerDetail> _comp = DoX().Compile(); //problem
static ClassX() { }
public static IQueryable<CustomerDetail> ConvertDetail(this IQueryable<Customer> query, List<int> mlist)
{
query.Select(_exp(mlist));
}
public static CODEDistrictDTO ConvertDetail(this Customer customer, List<int> mlist)
{
return _comp(customer,mlist);
}
private static Expression<Func<CODEDistrictEntity, CODEDistrictDTO>> DoX(List<int> mlist)
{
}
}
The problem in the static readonly fields!!!
Take another look at the syntax for how a Func<> is defined:
https://learn.microsoft.com/en-us/dotnet/api/system.func-2
https://learn.microsoft.com/en-us/dotnet/api/system.func-3
public delegate TResult Func<in T,out TResult>(T arg);
public delegate TResult Func<in T1,in T2,out TResult>(T1 arg1, T2 arg2);
The definition you have applied at the top for Func<Customer, CustomerDetail> then means that you are providing a delegate function that takes in one parameter of type Customer and returns a result of type CustomerDetail. This following block calls the delegate function _comp with the customer value as that parameter.
public static CODEDistrictDTO ConvertDetail(this Customer customer)
{
return _comp(customer); // <- Calls our delegate Func<Customer,CustomerDetail> with a Customer param, returns a CustomerDetail
}
In your updated code, you suddenly start trying to pass two parameters to that delegate function with _comp(customer,mlist), but it is only defined as having one. To change the delegate to expect two parameters, with the second being of type List<int>, then you would need to update that to private static readonly Func<Customer, List<int>, CustomerDetail> _comp = ...
Keep in mind this is only going to help you if your DoX.Compile() method will actually accept this signature - updating the Func does not mean your provided delegate will suddenly know what to do with the extra parameter if it doesn't already expect it.

How to convert Func<T, TResult> to Func<T>

I have Func<object, bool> myDelegate and
some variable like this:
object test = new object();
How can I pass myDelegate through to a method expecting a Func<bool> argument:
class FuncT
{
static void Main(string[] args)
{
object test = new object();
Func<object, bool> myDelegate = (x) => x != null;
// how to pass myDelegate to methodName so that it evaluates against 'test'?
methodName(myDelegate);
}
static void methodName(Func<bool> criteria)
{
Console.Out.WriteLine("Criteria: {0}", criteria());
}
}
As alternative, I can change the method to have signature like void methodName(object a, Func<object, bool> criteria) and call it methodName (test, myDelegate), but why? I already have test variable of object type, so I would like to tell myDelegate to use it inside the method, so that methodName would get only a delegate without parameters.

Check for null using generic delegate parameters with param keyword

I have a interesting case here . I have a method call as
bool pass= Check.CheckNotNull<RemoveRoleFromUserCommand>(x => x.RoleName, x => x.UserId);
Now I want to Make this method definition as something like this ..
public static void CheckNotNull<T>(params Expression<Func<T, object>>[] #params)
{
return #params.All(x=> ..... );
}
How to check for all of the values in #params delegate for all values that I have passed.
Well, if you want to invoke the delegates, you need an instance of T. So add that as an argument.
public static bool CheckNotNull<T>(T item, params Func<T, object>[] #params)
{
return #params.All(selector => selector(item) != null );
}
In response to the comment:
public static bool CheckNotNull<T>(T item, params Func<T, object>[] #params)
{
return #params.All(selector =>
{
var selected = selector(item);
return selected is string? string.IsNullOrEmpty(selected as string) : selected != null;
} );
}

Static dictionary containing delegates to instance methods

I have this method with a huge switch statement like this:
public bool ExecuteCommand(string command, string args)
{
bool result = false;
switch (command)
{
case "command1": result = Method1(args); break;
case "command2": result = Method2(args); break;
// etc.
}
return result;
}
private bool Method1(string args) {...}
Now I thought about replacing this with a dictionary of Func<> delegates so that I can eliminate the switch statement:
private Dictionary<string, Func<string, bool>> _commands = new ...;
public MyClass()
{
_commands.Add("command1", Method1);
// etc:
}
public bool ExecuteCommand(string command, string args)
{
return _commands[command](args);
}
The problem I see with this, is that a new Dictionary is instantiated and populated with each new instance of MyClass.
Is it possible to somehow make that Dictionary (containing delegates to instance methods) a static member, which would be initialized only once, in the static constructor?
E.g. something like this (does not work):
private static Dictionary<string, Func<string, bool>> _commands = new ...;
static MyClass()
{
// the following line will result in a compiler error:
// error CS0120: An object reference is required for the non-static field,
// method, or property 'MyClass.Method1(string, string)'
_commands.Add("command1", MyClass.Method1);
}
You can initialize it in the static constructor - but you'll need to create instances of MyClass, which may not be what you want, because I assume you want the command to execute "in the context of" the instance which Execute has been called on.
Alternatively, you can populate the dictionary with delegates which take an instance of MyClass as well, like this:
class MyClass
{
static Dictionary<string, Func<MyClass, string, bool>> commands
= new Dictionary<string, Func<MyClass, string, bool>>
{
{ "Foo", (#this, x) => #this.Foo(x) },
{ "Bar", (#this, y) => #this.Bar(y) }
};
public bool Execute(string command, string value)
{
return commands[command](this, value);
}
public bool Foo(string x)
{
return x.Length > 3;
}
public bool Bar(string x)
{
return x == "";
}
}
In theory I believe it should be doable without the lambda expression by creating an "open delegate", but it would need a bit more work using reflection. If you don't mind the ugliness and tiny performance penalty of the extra indirection, I think this approach should work quite well.

Calling a static method using a Type

How do I call a static method from a Type, assuming I know the value of the Type variable and the name of the static method?
public class FooClass {
public static FooMethod() {
//do something
}
}
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod() //works fine
if (t is FooClass) {
t.FooMethod(); //should call FooClass.FooMethod(); compile error
}
}
}
So, given a Type t, the objective is to call FooMethod() on the class that is of Type t. Basically I need to reverse the typeof() operator.
You need to call MethodInfo.Invoke method:
public class BarClass {
public void BarMethod(Type t) {
FooClass.FooMethod(); //works fine
if (t == typeof(FooClass)) {
t.GetMethod("FooMethod").Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
Of course in the above example you might as well call FooClass.FooMethod as there is no point using reflection for that. The following sample makes more sense:
public class BarClass {
public void BarMethod(Type t, string method) {
var methodInfo = t.GetMethod(method);
if (methodInfo != null) {
methodInfo.Invoke(null, null); // (null, null) means calling static method with no parameters
}
}
}
public class Foo1Class {
static public Foo1Method(){}
}
public class Foo2Class {
static public Foo2Method(){}
}
//Usage
new BarClass().BarMethod(typeof(Foo1Class), "Foo1Method");
new BarClass().BarMethod(typeof(Foo2Class), "Foo2Method");
Note, that as 10 years have passed. Personally, I would add extension method:
public static TR Method<TR>(this Type t, string method, object obj = null, params object[] parameters)
=> (TR)t.GetMethod(method)?.Invoke(obj, parameters);
and then I could call it with:
var result = typeof(Foo1Class).Method<string>(nameof(Foo1Class.Foo1Method));
Check into the MethodInfo class and the GetMethod() methods on Type.
There are a number of different overloads for different situations.

Categories

Resources