How could I implement my own deferred execution mechanism in C#?
So for instance I have:
string x = DoFoo();
Is it possible to perform some magic so that DoFoo does not execute until I "use" x?
You can use lambdas/delegates:
Func<string> doit = () => DoFoo();
// - or -
Func<string> doit = DoFoo;
Later you can invoke doit just like a method:
string x = doit();
I think the closest you can get is something like this:
Lazy<string> x = DoFoo;
string y = x; // "use" x
With a definition of Lazy<T> similar to this (untested):
public class Lazy<T>
{
private readonly Func<T> func;
private bool hasValue;
private T value;
public Lazy(Func<T> func)
{
this.func = func;
this.hasValue = false;
}
public static implicit operator Lazy<T>(Func<T> func)
{
return new Lazy<T>(func);
}
public static implicit operator T(Lazy<T> lazy)
{
if (!lazy.hasValue)
{
lazy.value = lazy.func();
lazy.hasValue = true;
}
return lazy.value;
}
}
Unfortunately, it seems that the compiler's type inferencing algorithms can't auto-infer the type of the Func<T> and so can't match it to the implicit conversion operator. We need to explicitly declare the delegate's type, which makes the assignment statements more verbose:
// none of these will compile...
Lazy<string> x = DoFoo;
Lazy<string> y = () => DoFoo();
Lazy<string> z = delegate() { return DoFoo(); };
// these all work...
Lazy<string> a = (Func<string>)DoFoo;
Lazy<string> b = (Func<string>)(() => DoFoo());
Lazy<string> c = new Func<string>(DoFoo);
Lazy<string> d = new Func<string>(() => DoFoo());
Lazy<string> e = new Lazy<string>(DoFoo);
Lazy<string> f = new Lazy<string>(() => DoFoo);
One option is to use the Lazy<T> class, formerly from the parallel extensions library now a part of the .Net Framework 4.0.
Reference: http://msdn.microsoft.com/en-us/library/dd642331(VS.100).aspx
It allows you to delay process data in a thread aware manner.
While it's somewhat dirty you could always use the yield keyword:
public IEnumerable<int> DoFoo() {
Console.WriteLine("doing foo");
yield return 10;
}
[Test]
public void TestMethod()
{
var x = DoFoo();
Console.WriteLine("foo aquired?");
Console.WriteLine(x.First());
}
Instead of passing a string x, pass a delegate that procures you a string
Func<String> fooFunc=()=>DoFoo();
Why not just not call 'DoFoo()' until you want to?
-- Edit
I mean, what do you mean "use"
For example, if you want it to be called when '.ToString()' called, you can always inherit the class and implement your function there (but this would be quite unintuitive IMHO).
You pretty much describe LINQ in action. A linq query describes how to obtain the data, but data is retrieved (DoFunc is called) only when the query is iterated. Consider if you can change your design to accept IQueryable<string> where you need a string.
Related
I know I can use an anonymous method or a lambda expression, e.g:
myObjects.RemoveAll(delegate (MyObject m) { return m.X >= 10); });
myObjects.RemoveAll(m => m.X >= 10));
But I cannot figure out whether a regular delegate (delegate bool X (MyObject o) ) could be used, my attempts fail.
I.e. creating a delegate, set it to a method a then pass the delegate instance as the predicate.
For compatibility reasons, you must instantiate the delegate explicitly, even if the signature of a different delegate is compatible. This is not very well documented, see discussion in this question.
Example for the (very verbose) syntax do do this:
public void Test()
{
var l = new List<MyObject>();
// The following three lines
var x = new X(my => string.IsNullOrEmpty(my.Name));
var p = new Predicate<MyObject>(x);
l.RemoveAll(p);
// ...will accomplish the same as:
l.RemoveAll(my => string.IsNullOrEmpty(my.Name));
}
private delegate bool X(MyObject m);
private class MyObject
{
public string Name { get; set; }
}
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.
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);
Suppose I have a complex lambda expression as follows:
x => x.A.HasValue || (x.B.HasValue && x.C == q) || (!x.C.HasValue && !x.A.HasValue) || //...expression goes on
I want to use this as an Expression<Func<T,bool> in (e.g. Linq-To-Entities) Queryable.Where method. I also want to use it in the Enumerable.Where method, but the Where method only accepts a Func<T,bool>, not an Expression<Func<T,bool>.
The lambda syntax itself can be used to generate either an Expression<Func<T,bool>> or a Func<T,bool> (or any delegate type for that matter), but in this context it cannot generate more than one at once.
For example, I can write:
public Expression<Func<Pair,bool>> PairMatchesExpression()
{
return x => x.A == x.B;
}
as easily as I can write:
public Func<Pair,bool> PairMatchesDelegate()
{
return x => x.A == x.B;
}
The problem is that I cannot use the same exact lambda expression (i.e. x => x.A == x.B) in both ways, without physically duplicating it into two separate methods with two different return types, in spite of the compiler's ability to compile it into either one.
In other words, if I'd like to use the lambda expression in the Queryable methods, then I have to use the Expression method signature. Once I do that however, I cannot use it as a Func as easily as I could have had I just declared the method return type as Func. Instead, I now have to call Compile on the Expression and then worry about caching the results manually like so:
static Func<Pair,bool> _cachedFunc;
public Func<Pair,bool> PairMatchesFunc()
{
if (_cachedFunc == null)
_cachedFunc = PairMatchesExpression().Compile();
return _cachedFunc;
}
Is there a solution to this problem so that I can use the lambda expression in a more general way without it being locked down to a particular type at compile-time?
Unfortunately, I can see no way to truly get, at compile time, a Func and an Expression from the same lambda. However, you could at least encapsulate away the difference, and you can also defer the compilation of the Func until the first time it's used. Here's a solution that makes the best of things and may meet your needs, even though it doesn't quite go all the way to what you really wanted (compile-time evaluation of both the Expression and the Func).
Please note that this works fine without using the [DelegateConstraint] attribute (from Fody.ExtraConstraints), but with it, you will get compile-time checking of the constructor parameter. The attributes make the classes act like they have a constraint where T : Delegate, which is not currently supported in C#, even though it is supported in the ILE (not sure if I'm saying that right, but you get the idea).
public class VersatileLambda<[DelegateConstraint] T> where T : class {
private readonly Expression<T> _expression;
private readonly Lazy<T> _funcLazy;
public VersatileLambda(Expression<T> expression) {
if (expression == null) {
throw new ArgumentNullException(nameof(expression));
}
_expression = expression;
_funcLazy = new Lazy<T>(expression.Compile);
}
public static implicit operator Expression<T>(VersatileLambda<T> lambda) {
return lambda?._expression;
}
public static implicit operator T(VersatileLambda<T> lambda) {
return lambda?._funcLazy.Value;
}
public Expression<T> AsExpression() { return this; }
public T AsLambda() { return this; }
}
public class WhereConstraint<[DelegateConstraint] T> : VersatileLambda<Func<T, bool>> {
public WhereConstraint(Expression<Func<T, bool>> lambda)
: base(lambda) { }
}
The beauty of the implicit conversion is that in contexts where a specific Expression<Func<>> or Func<> is expected, you don't have to do anything at all, just, use it.
Now, given an object:
public partial class MyObject {
public int Value { get; set; }
}
That is represented in the database like so:
CREATE TABLE dbo.MyObjects (
Value int NOT NULL CONSTRAINT PK_MyObjects PRIMARY KEY CLUSTERED
);
Then it works like this:
var greaterThan5 = new WhereConstraint<MyObject>(o => o.Value > 5);
// Linq to Objects
List<MyObject> list = GetObjectsList();
var filteredList = list.Where(greaterThan5).ToList(); // no special handling
// Linq to Entities
IQueryable<MyObject> myObjects = new MyObjectsContext().MyObjects;
var filteredList2 = myObjects.Where(greaterThan5).ToList(); // no special handling
If implicit conversion isn't suitable, you can cast explicitly to the target type:
var expression = (Expression<Func<MyObject, bool>>) greaterThan5;
Note that you don't really need the WhereConstraint class, or you could get rid of VersatileLambda by moving its contents to WhereConstraint, but I liked making the two separate (as now you can use VersatileLambda for something that returns other than a bool). (And this difference is largely what sets apart my answer from Diego's.) Using VersatileLambda as it is now looks like this (you can see why I wrapped it):
var vl = new VersatileLambda<Func<MyObject, bool>>(o => o.Value > 5);
I have confirmed that this works perfectly for IEnumerable as well as IQueryable, properly projecting the lambda expression into the SQL, as proven by running SQL Profiler.
Also, you can do some really cool things with expressions that can't be done with lambdas. Check this out:
public static class ExpressionHelper {
public static Expression<Func<TFrom, TTo>> Chain<TFrom, TMiddle, TTo>(
this Expression<Func<TFrom, TMiddle>> first,
Expression<Func<TMiddle, TTo>> second
) {
return Expression.Lambda<Func<TFrom, TTo>>(
new SwapVisitor(second.Parameters[0], first.Body).Visit(second.Body),
first.Parameters
);
}
// this method thanks to Marc Gravell
private class SwapVisitor : ExpressionVisitor {
private readonly Expression _from;
private readonly Expression _to;
public SwapVisitor(Expression from, Expression to) {
_from = from;
_to = to;
}
public override Expression Visit(Expression node) {
return node == _from ? _to : base.Visit(node);
}
}
}
var valueSelector = new Expression<Func<MyTable, int>>(o => o.Value);
var intSelector = new Expression<Func<int, bool>>(x => x > 5);
var selector = valueSelector.Chain<MyTable, int, bool>(intSelector);
You can create an overload of Chain that takes a VersatileLambda as the first parameter, and returns a VersatileLambda. Now you're really sizzling along.
You could create a wrapper class. Something like this:
public class FuncExtensionWrap<T>
{
private readonly Expression<Func<T, bool>> exp;
private readonly Func<T, bool> func;
public FuncExtensionWrap(Expression<Func<T, bool>> exp)
{
this.exp = exp;
this.func = exp.Compile();
}
public Expression<Func<T, bool>> AsExp()
{
return this;
}
public Func<T, bool> AsFunc()
{
return this;
}
public static implicit operator Expression<Func<T, bool>>(FuncExtensionWrap<T> w)
{
if (w == null)
return null;
return w.exp;
}
public static implicit operator Func<T, bool>(FuncExtensionWrap<T> w)
{
if (w == null)
return null;
return w.func;
}
}
And then it would be used like this:
static readonly FuncExtensionWrap<int> expWrap = new FuncExtensionWrap<int>(i => i == 2);
// As expression
Expression<Func<int, bool>> exp = expWrap;
Console.WriteLine(exp.Compile()(2));
// As expression (another way)
Console.WriteLine(expWrap.AsExp().Compile()(2));
// As function
Func<int, bool> func = expWrap;
Console.WriteLine(func(1));
// As function(another way)
Console.WriteLine(expWrap.AsFunc()(2));
Here is one workaround. It generates an explicit class for the expression (as the compiler would do under the hood anyway with lambda expressions that require a function closure) instead of just a method, and it compiles the expression in a static constructor so it doesn't have any race conditions that could result in multiple compilations. This workaround still incurs an additional runtime delay as a result of the Compile call which could otherwise be offloaded to build-time, but at least it's guaranteed to run only once using this pattern.
Given a type to be used in the expression:
public class SomeClass
{
public int A { get; set; }
public int? B { get; set; }
}
Build an inner class instead of a method, naming it whatever you would have named the method:
static class SomeClassMeetsConditionName
{
private static Expression<Func<SomeClass,bool>> _expression;
private static Func<SomeClass,bool> _delegate;
static SomeClassMeetsConditionName()
{
_expression = x => (x.A > 3 && !x.B.HasValue) || (x.B.HasValue && x.B.Value > 5);
_delegate = _expression.Compile();
}
public static Expression<Func<SomeClass, bool>> Expression { get { return _expression; } }
public static Func<SomeClass, bool> Delegate { get { return _delegate; } }
}
Then instead of using Where( SomeClassMeetsConditionName() ), you simply pass SomeClassMeetsConditionName followed by either .Delegate or .Expression, depending on the context:
public void Test()
{
IEnumerable<SomeClass> list = GetList();
IQueryable<SomeClass> repo = GetQuery();
var r0 = list.Where( SomeClassMeetsConditionName.Delegate );
var r1 = repo.Where( SomeClassMeetsConditionName.Expression );
}
As an inner class, it could be given an access level just like a method and accessed just like a method, and even collapsed all at once like a method, so if you can stand to look at the class instead of a method, this is a functional workaround. It could even be made into a code template.
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);