In regards to the answer for this question Passing DataContext into Action(), how do I return a value from action(db)?
SimpleUsing.DoUsing(db => {
// do whatever with db
});
Should be more like:
MyType myType = SimpleUsing.DoUsing<MyType>(db => {
// do whatever with db. query buit using db returns MyType.
});
You can use Func<T, TResult> generic delegate. (See MSDN)
Func<MyType, ReturnType> func = (db) => { return new MyType(); }
Also there are useful generic delegates which considers a return value:
Converter<TInput, TOutput> (MSDN)
Predicate<TInput> - always return bool (MSDN)
Method:
public MyType SimpleUsing.DoUsing<MyType>(Func<TInput, MyType> myTypeFactory)
Generic delegate:
Func<InputArgumentType, MyType> createInstance = db => return new MyType();
Execute:
MyType myTypeInstance = SimpleUsing.DoUsing(
createInstance(new InputArgumentType()));
OR explicitly:
MyType myTypeInstance = SimpleUsing.DoUsing(db => return new MyType());
Your static method should go from:
public static class SimpleUsing
{
public static void DoUsing(Action<MyDataContext> action)
{
using (MyDataContext db = new MyDataContext())
action(db);
}
}
To:
public static class SimpleUsing
{
public static TResult DoUsing<TResult>(Func<MyDataContext, TResult> action)
{
using (MyDataContext db = new MyDataContext())
return action(db);
}
}
This answer grew out of comments so I could provide code. For a complete elaboration, please see #sll's answer below.
Use Func<T> rather than Action<T>.
Action<T> acts like a void method with parameter of type T, while Func<T> works like a function with no parameters and which returns an object of type T.
If you wish to give parameters to your function, use Func<TParameter1, TParameter2, ..., TReturn>.
You can also take advantage of the fact that a lambda or anonymous method can close over variables in its enclosing scope.
MyType result;
SimpleUsing.DoUsing(db =>
{
result = db.SomeQuery(); //whatever returns the MyType result
});
//do something with result
In addition to ssls answer: For a software we call a lot of "micro methods" to query this and that from the local machine. Sometimes exceptions appear (file / folder not existing, etc). In order to not repeat our self over and over with try/catch blocks, we used ssls approach with return values:
private T ExecuteAndCatch<T>(Func<T> action, T defaultReturn)
{
try
{
return action();
}
catch (Exception ex)
{
Log.e("Exception during ExecuteAndCatch", ex);
return defaultReturn;
}
}
Example of mentioned micro-methods:
private Boolean CheckKasperskyInstalled() => System.IO.File.Exists(Environment.ExpandEnvironmentVariables(#"%pf_x86%\Kaspersky Lab\Kaspersky Endpoint Security for Windows\avp.exe"));
private Boolean CheckKasperskyRunning() => System.Diagnostics.Process.GetProcessesByName("avp").Length > 0;
And when using, we no longer have to care if these Methods might throw an exception for whatever reason:
cci = new ComputerComplianceInfo();
cci.KasperskyInstalled = ExecuteAndCatch(() => CheckKasperskyInstalled(), false);
cci.KasperskyRunning = ExecuteAndCatch(() => CheckKasperskyRunning(), false);
Related
I am wondering if there is some way to optimize the using statement to declare and assign its output together (when it is a single value).
For instance, something similar to the new way to inline declare the result variable of an out parameter.
//What I am currently doing:
string myResult;
using(var disposableInstance = new myDisposableType()){
myResult = disposableInstance.GetResult();
}
//That would be ideal
var myResult = using(var disposableInstance = new myDisposableType()){
return disposableInstance.GetResult();
}
//That would be great too
using(var disposableInstance = new myDisposableType(), out var myResult){
myResult = disposableInstance.GetResult();
}
Thanks for your input.
You can use extension method to "simplify" this usage pattern:
public static class Extensions {
public static TResult GetThenDispose<TDisposable, TResult>(
this TDisposable d,
Func<TDisposable, TResult> func)
where TDisposable : IDisposable {
using (d) {
return func(d);
}
}
}
Then you use it like this:
string myResult = new myDisposableType().GetThenDispose(c => c.GetResult());
This is funny, because I started reading Functional Programming in C# a couple of days ago, and one of the first examples is along the lines of:
public static TResult Using<TDisposable, TResult>(TDisposable disposable, Func<TDisposable, TResult> func)
where TDisposable : IDisposable
{
using (disposable)
{
return func(disposable);
}
}
Usage:
var result = Using(new DbConnection(), x => x.GetResult());
Notice that, unlike the other answers posted, this function has absolutely no responsibility but get the result of func, regardless of TDisposable.
No, there is no such shortcut. Your original way is right.
You could wrap this in a function if you do it often enough
public class Utilities
{
public static TReturn GetValueFromUsing<T,TReturn>(Func<T,TReturn> func) where T : IDisposable, new()
{
TReturn result = default(TReturn)
using(var instance = new T())
result = func(instance);
return result;
}
}
usage
var result = Utilities.GetValueFromUsing<myDisposableType,string>(x => x.GetResult());
But man would that be overkill.
The using instruction cannot be used as r-value, and therefore there is no way to assign a value from it.
However, there is a special case to this, and you can use it where convenient: You can return a result from inside the using block.
int F(int arg)
{
using (disposable = GetObj())
{
return disposable.Calculate(arg);
}
}
This form is often communicating the purpose better than a local variable assignment. You can even turn it into a template method, where the method would apply the using construct and then call a strategy and return its result.
class Useful<TDisposable> where TDisposable : IDisposable
{
private Func<TDisposable> Factory { get; }
public Useful(Func<TDisposable> factory)
{
this.Fatory = factory;
}
public TResult SafeDo<TResult>(Func<TDisposable, TResult> operation)
{
using (TDisposable obj = this.Factory())
{
return operation(obj);
}
}
}
This class is completely reusable and its single responsibility is to ensure that disposable components are disposed on use. Instead of working directly with a disposable class, you can wrap it into this wrapper class and consume it that way and you'll have a strict lifetime control over the disposable objects:
void Worker(Useful<MyDisposableClass> wrapper)
{
int arg = 5;
wrapper.SafeDo(disp => disp.Calculate(arg);
}
In this piece of code, the disp object would be constructed and disposed correctly. A concrete argument that would be required by the operation arg is taken from the closure.
I am attempting to call an awaitable method via MethodInfo invoke.
The MethodInfo.Invoke() returns type object that needs to be cast as a Task before I can await it. If I manually cast the return type with a generic parameter of Task, the process works correctly.
However, I have a number of these methods to call that have different return types. How do I handle the return type?
public class Repository
{
public IEnumerable<Foo> GetListAsync(int criteria)
{
return new List<Foo> {new Foo {Bar = "1"}, new Foo {Bar = "2"}};
}
}
public class Foo
{
public string Bar { get; set; }
}
public class Precache
{
public static void RegisterPreCache(Repository instanceObject)
{
var preCachedType = typeof (Repository);
var preCachableMethods =
preCachedType
.GetMethods();
foreach (var cachableMethod in preCachableMethods)
{
var resultTask =
(Task<IEnumerable<Foo>>) cachableMethod.Invoke(instanceObject,
new object[]
{1});
Task.Run(async () => await resultTask).Wait();
}
}
}
I can get the return type easily from cacheableMethod.ReturnType property. How can I do the cast dynamically? Without the cast, I cannot await the invocation.
I have tried casting simply as Task which of course does not work (EDIT: It does work). I have tried passing all of the parameters into a new generic method, but if I do not specify the generic type must be a Task (where T : Task), I get a compile time error that there is no definition for GetAwaiter.
private static void CallExpression<T>(T returnType, MethodInfo
cachableMethod, object instanceObject, object[] parameters)
{
var resultTask = (T) cachableMethod.Invoke(instanceObject, parameters);
Task.Run(async () => await resultTask).Wait();
}
Thank you
With many thanks to Jon Skeet, was able to determine that the issue was the fact that I was making the cast too specific.
var resultTask = (Task) cachableMethod.Invoke(...)
allows the MethodInfo invocation to be awaited.
The answer is already posted:
var resultTask = (Task)cachableMethod.Invoke(...)
However, be aware:
You can await on anything besides Task and Task<T>, so if your downstream method returns something that can be awaited on with an extension method, that approach will not work.
The problem number 1 can be a problem in future C# 7 feature, where you can return a custom awaitable type in async method besides Task or Task<T>
Is it possible in C# to get a reference to a member function without specifying the object, so that it is usable like a static extension method, taking the object as first parameter?
class Handler
{
public void Add(int value) { ... }
}
static class HandlerExtensions
{
public static void AddEx(this Handler instance, int value) { ... }
}
var x = new Handler();
// possible:
Action<int> func1 = x.Add;
Action<Handler, int> func2 = HandlerExtensions.AddEx;
// not possible?
Action<Handler, int> func3 = Handler::Add;
Why would I want to do that? To specify methods to call in a class before having an actual object to work with:
// current solution:
void RegisterDto<DataType>(Func<Handler, Action<DataType>> handler) { ... }
RegisterDto<int>(x => x.Add);
// desired solution:
void RegisterDto<DataType>(Action<Handler, DataType> handler) { ... }
RegisterDto<int>(Handler::Add); // <--- does syntax for this exist?
If you mean "can you create a delegate like that" then the answer is "yes, but it's slightly ugly". I don't think you can use a method group conversion, but you can use reflection and Delegate.CreateDelegate, e.g.
MethodInfo method = typeof(Handler).GetMethod("Add");
var action = (Action<Handler, int>)
Delegate.CreateDelegate(typeof(Action<Handler, int>), method);
It would be nice to have a method group conversion here, I agree.
This might not work for you use-case, but you can create a delegate with
Action<Handler, int> f = (h, v) => h.Add(v);
And to use it
var handler = new Handler();
f(handler, 100);
If you don't want to evaluate it each time, maybe you could make it Lazy
Func<Lazy<Handler>, Action<int>> addMethod = target => target.Value.Add;
// example of usage
var lazyHandler = new Lazy<Handler>();
Test(addMethod(lazyHandler), 1);
I am trying to achieve the following:
this.helper.Verify(i => i.SomeModule.SomeMethod);
Where:
i is a known type.
SomeModule is a public property of this type.
SomeMethod is the name of the method (passed as delegate I assume).
I would like to be able to avoid specifying the generic types in the Verify method.
Thats how far I've been able to go:
public void Verify<TProp, TResult>(
Expression<Func<KnownType, TProp>> moduleExpression,
Expression<Func<TProp, TResult>> methodExpression)
{
var moduleIdentifier = (moduleExpression.Body as MemberExpression).Member.Name;
var methodIdentifier = (methodExpression.Body as MethodCallExpression).Method.Name;
this.Verify(moduleIdentifier, methodIdentifier, state);
}
But this forces me to write the argument values for the methodExpression, like:
this.helper.Verify(
i => i.SomeModule,
m => m.SomeMethod(arg1, arg2));
Is there a way to achieve what I am looking for?
Finally I end up with a solution that requires delegates.
I need to analyze an expression that can have multiple arguments, like:
i => i.Car.Engine.Intake.Open()
I will extract the last two arguments as a "module" and "method":
public class ExpressionTools
{
public string GetLastInstanceName<TProp, TDelegate>(Expression<Func<TProp, TDelegate>> expression)
{
var unaryExpression = (UnaryExpression)expression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (MemberExpression)methodCallExpression.Arguments.Reverse().Skip(1).First();
var instanceName = methodInfoExpression.Member.Name;
return instanceName;
}
public string GetMethodName<TProp, TDelegate>(Expression<Func<TProp, TDelegate>> expression)
{
var unaryExpression = (UnaryExpression)expression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
var methodInfo = (MemberInfo)methodInfoExpression.Value;
return methodInfo.Name;
}
}
Solution with delegates
A class with generics can be reused since the delegates are not necessary to analyze the expression:
public class Verifier
{
public void Verify<TDelegate>(Expression<Func<KnownType, TDelegate>> methodExpression)
{
var tools = new ExpressionTools();
var moduleName = tools.GetLastInstanceName(methodExpression);
var methodName = tools.GetMethodName(methodExpression);
// My logic.
}
}
Now I need to create the delegates, For that I created a file and declared them without a class:
namespace Whatever
{
public delegate void VoidDelegate();
public delegate void VoidBoolDelegate(bool value);
// etc...
}
Finally, I need to maintain a class that has the same method overloaded with the different delegates.
public class FakeExtensions
{
public static void Verify(
this Fake fake,
Expression<Func<KnownType, VoidDelegate>> methodExpression)
{
var tools = new ExpressionTools();
var facilitator = new Verifier(fake, tools);
facilitator.Verify(methodExpression);
}
public static void Verify(
this Fake fake,
Expression<Func<KnownType, VoidBoolDelegate>> methodExpression)
{
var tools = new ExpressionTools();
var facilitator = new Verifier(fake, tools);
facilitator.Verify(methodExpression);
}
}
Alternative solution without delegates
The easiest solution would be to pass a default value for each parameter, but that would express that the values are also verified, which is not the case. I really dislike the idea of having something like this:
this.helper.Verify(i => i.SomeModule.SomeMethod(0, false, 0.0, null);
Since Moq is part of our testing framework, it is possible to use It.IsAny as a value for each parameter of a method call, wich expresses that the values don't matter:
this.helper.Verify(i => i.SomeModule.SomeMethod(It.IsAny<int>, It.IsAny<bool>, It.IsAny<double>, It.IsAny<SomeType>);
Why did I choose the delegates solution
I have to verify some calls on a low-level 3rd party API that has methods with up to 100 parameters. I think that the burden of maintaining a delegates list and method overloads pays off in maintainability, readability and ease of use.
I know there are a few answers on the site on this and i apologize if this is in any way duplicate, but all of the ones I found does not do what I am trying to do.
I am trying to specify method info so I can get the name in a type safe way by not using strings.
So I am trying to extract it with an expression.
Say I want to get the name of a method in this interface:
public interface IMyInteface
{
void DoSomething(string param1, string param2);
}
Currently I can get the name using THIS method:
MemberInfo GetMethodInfo<T>(Expression<Action<T>> expression)
{
return ((MethodCallExpression)expression.Body).Method;
}
I can call the helper method as follows:
var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething(null, null));
Console.WriteLine(methodInfo.Name);
But I am looking for the version that I can get the method name without specifying the parameters (null, null)
like this:
var methodInfo = GetMethodInfo<IMyInteface>(x => x.DoSomething);
But all attempts fail to compile
Is there a way to do this?
x => x.DoSomething
In order to make this compilable I see only two ways:
Go non-generic way and specify it's parameter as Action<string, string>
Specify Action<string, string> as your target delegate type by yourself: GetMethodInfo<IMyInteface>(x => new Action<string,string>(x.DoSomething))
if you are ok to go with second one, which allows you to omit arguments then you can write your GetMethodInfo method as follows:
MemberInfo GetMethodInfo<T>(Expression<Func<T, Delegate>> expression)
{
var unaryExpression = (UnaryExpression) expression.Body;
var methodCallExpression = (MethodCallExpression) unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression) methodCallExpression.Arguments.Last();
var methodInfo = (MemberInfo) methodInfoExpression.Value;
return methodInfo;
}
It works for your interface, but probably some generalization will be required to make this working with any method, that's up to you.
The following is compatible with .NET 4.5:
public static string MethodName(LambdaExpression expression)
{
var unaryExpression = (UnaryExpression)expression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodCallObject = (ConstantExpression)methodCallExpression.Object;
var methodInfo = (MethodInfo)methodCallObject.Value;
return methodInfo.Name;
}
You can use it with expressions like x => x.DoSomething, however it would require some wrapping into generic methods for different types of methods.
Here is a backwards-compatible version:
private static bool IsNET45 = Type.GetType("System.Reflection.ReflectionContext", false) != null;
public static string MethodName(LambdaExpression expression)
{
var unaryExpression = (UnaryExpression)expression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
if (IsNET45)
{
var methodCallObject = (ConstantExpression)methodCallExpression.Object;
var methodInfo = (MethodInfo)methodCallObject.Value;
return methodInfo.Name;
}
else
{
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
var methodInfo = (MemberInfo)methodInfoExpression.Value;
return methodInfo.Name;
}
}
Check this sample code on Ideone.
Note, that Ideone does not have .NET 4.5.
The problem with this is that x.DoSomething represents a method group. And you have to somehow explicitly specify what delegate type do you want to convert that method group into, so that the correct member of the group can be selected. And it doesn't matter if that group contains only one member.
The compiler could infer that you mean that one, but it doesn't do that. (I think it's this way so that your code won't break if you add another overload of that method.)
Snowbear's answer contains good advice on possible solutions.
This is a new answer to an old question, but responds to the "verbose" complaint of the accepted answer. It requires more code, but the result is a syntax like:
MemberInfo info = GetActionInfo<IMyInterface, string, string>(x => x.DoSomething);
or, for methods with a return value
MemberInfo info = GetFuncInfo<IMyInterface, object, string, string>(x => x.DoSomethingWithReturn);
where
object DoSomethingWithReturn(string param1, string param2);
Just like the framework provides Action<> and Func<> delegates up to 16 parameters, you have to have GetActionInfo and GetFuncInfo methods that accept up to 16 parameters (or more, although I'd think refactoring is wise if you have methods with 16 parameters). A lot more code, but an improvement in the syntax.
If you are ok with using the nameof() operator you can use the following approach.
One of the benefits is not having to unwrap an expression tree or supply default values or worry about having a non-null instance of the type with the method.
// As extension method
public static string GetMethodName<T>(this T instance, Func<T, string> nameofMethod) where T : class
{
return nameofMethod(instance);
}
// As static method
public static string GetMethodName<T>(Func<T, string> nameofMethod) where T : class
{
return nameofMethod(default);
}
Usage:
public class Car
{
public void Drive() { }
}
var car = new Car();
string methodName1 = car.GetMethodName(c => nameof(c.Drive));
var nullCar = new Car();
string methodName2 = nullCar.GetMethodName(c => nameof(c.Drive));
string methodName3 = GetMethodName<Car>(c => nameof(c.Drive));
If your application would allow a dependency on Moq (or a similar library), you could do something like this:
class Program
{
static void Main(string[] args)
{
var methodName = GetMethodName<IMyInteface>(x => new Action<string,string>(x.DoSomething));
Console.WriteLine(methodName);
}
static string GetMethodName<T>(Func<T, Delegate> func) where T : class
{
// http://code.google.com/p/moq/
var moq = new Mock<T>();
var del = func.Invoke(moq.Object);
return del.Method.Name;
}
}
public interface IMyInteface
{
void DoSomething(string param1, string param2);
}