Can I use a standard delegate instead a predicate? - c#

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; }
}

Related

C# member method as static method ("reversed extension method")

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);

Using Implicit Type Syntax on Method Return

Not exactly how sure how to title this question, so I hope the title works.
The question is, can I use something similar to implicit type syntax on method calls. For example, this is the implicit type syntax I am referring to:
var x = new Y(){Foo = "Bar", Id = 1};
And I want to do something like this:
var x = myInstance.CreateItem(){Foo = "Bar", Id = 1};
Is there anything in C# that supports something like this? I don't want to do:
x.Foo = "Bar";
x.Id = 1;
...
Please note that CreateItem returns a dynamic type. The CreateItem method and its class cannot be modified.
I would settle for something similar to the With statement in VB.
Thanks in advance.
UPDATE: Attempting Mark Brackett's solution yielded this code:
TaskItem item = outlook.CreateItem(OlItemType.olTaskItem)._((Action<dynamic>)(i =>
{
i.Subject = "New Task";
i.StartDate = DateTime.Now;
i.DueDate = DateTime.Now.AddDays(1);
i.ReminderSet = false;
i.Categories = "#Work";
i.Sensitivity = OlSensitivity.olPrivate;
i.Display = true;
}));
...
public static class Extension
{
public static T _<T>(this T o, System.Action<dynamic> initialize) where T : class
{
initialize(o);
return o;
}
}
The only problem now is that the extension method doesn't seem to be binding to System._ComObject because I get this error: System._ComObject' does not contain a definition for '_'.
It's called an "object initializer", and no - it's not available for return values (or really, anytime other than with a new statement).
Syntax wise, about the closest I can think of would be to use an Action delegate (which requires changes to the Builder):
MyItem CreateItem(Action<MyItem> afterCreate) {
var i = new MyItem();
if (afterCreate != null) afterCreate(i);
return i;
}
var x = Builder.CreateItem(i => { i.Foo = "Bar"; i.Id = 1; });
If you're in a JavaScripty mood for short method names for commonly used functions, and can't change the Builder, I guess an extension method would also work:
public static T _<T>(this T o, Action<T> initialize) where T : class {
initialize(o);
return o;
}
var x = Builder.CreateItem()._(i => { i.Foo = "Bar"; i.Id = 1; });
Here's a twist for you. CreateItem() returns a dynamic type
Contrary to my comment, dynamic does require a few changes. You need to cast to object or the lambda will complain, and then you need to specify dynamic as T or it'll be inferred as object. Or, create your extension method with Action<dynamic> and no type arguments.
object CreateItem() {
return (object)Builder.CreateItem();
}
public static dynamic __(this object o, Action<dynamic> initialize) {
initialize(o);
return o;
}
var x = CreateItem().__(i => { i.Foo = "Bar"; i.Id = 1; });
You could use named arguments to the factory method:
public static Y Builder.CreateItem(string foo = "", int bar = 0)
{
return new Y() {Foo = foo, Bar = bar};
}
// called like so:
var x = Builder.CreateItem(Foo: "Bar", Id: 1);
You can specify 'public properties' in the constructor of the class but you cannot do that with methods
because
This rules only apply to member properties which is not possible with methods
You can not give public modofier in fields in the method so there is no possibility atall
When you do
var a = new MyClass{Foo="",Id=""};
You are defining properties of the class of this constructor MyClass()
You cannot do that with static or instance method

Get the name of a method using an expression

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);
}

C# List.Find method - how can I pass a value into the predicate?

I can't work out how to do a "find" on a List I have based on use of a value that I'll pass in at run time. If you see my below code, I want to be able to find the CustomClass in the List for which it's Path parameter is equal to X, where X will be defined at run time.
Any ideas how to do such a find on a List? Or is this not possible without writing an iterator and doing the find manually? In which case perhaps there is a key'ed collection I should look at using instead?
private List<CustomClass> files;
public void someMethod()
{
Uri u= new Uri(www.test.com);
CustomClass cc = this.files.find( matchesUri(u) ); // WON'T LET ME DO THIS
}
private static bool matchesUri(List<CustomClass> cc, Uri _u)
{
return cc.Path == _u; }
public class CustomClass
{
private Uri path;
public Uri Path
{
get { return this.path; }
set { this.path = value; }
}
}
PS. I must admit I don't quite follow the predicate stuff in the doco at http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx
Use a lambda:
Uri u = new Uri("www.test.com");
CustomClass cc = this.files.Find(cc => cc.Path == u);
or if you still want a named method:
static bool matchesUri(CustomClass cc, Uri _u)
{
return cc.Path == _u;
}
Uri u = new Uri("www.test.com");
CustomClass cc = this.files.Find(cc => matchesUri(cc, u));
You can write
CustomClass cc = this.files.Find( p=> p.Path == u );
The Find() method returns null if no element was found that matches the predicate.
For completeness sake only, here is what you would do if you didn't want to use a lambda:
// Predicate must be a method with a single parameter,
// so we must pass the other parameter in constructor
public class UriMatcher
{
private readonly Uri _u;
public UriMatcher(Uri u)
{
_u = u;
}
// Match is Predicate<CustomClass>
public bool Match(CustomClass cc)
{
return cc.Path == _u;
}
}
And then use it as:
public void someMethod()
{
Uri u = new Uri("www.test.com");
UriMatcher matcher = new UriMatcher(u);
CustomClass cc = this.files.Find(matcher.Match);
}
Note that you are passing a reference to a method, not the result of the method -- Match vs Match().
Check this thread also: Predicate Delegates in C#.
public void someMethod()
{
Uri u= new Uri("www.test.com");
CustomClass cc = this.files.find( p => { return p.Path == u; } );
}
Try using anonymous method for search and use any local variable you wish inside of it. If that is not satisfactory, call out your normally defined delegate method.
.NET 2.0 answer using an anonymous delegate (note that this only works for C#, VB.NET does not have anonymous delegates).
public void someMethod()
{
Uri u= new Uri("www.test.com");
CustomClass cc = this.files.find(delegate(CustomClass oTemp) { return oTemp.Path == u;});
}
In Pavel's post marked as answer, I think the line:
CustomClass cc = this.files.Find(cc => cc.Path == u);
should be instead like:
CustomClass cc = this.files.Find(cc2 => cc2.Path == u);
This is because the expresion to the left of => is a variable definition (the type is inferred from the expression) - The compiler would gives a redefinition error otherwise.
This expression can also be written with an explicit definition as:
CustomClass cc = this.files.Find((CustomClass cc2) => cc2.Path == u);
Here is a solution that I used. I needed to pass several arguments and didn't want to use anything that would prevent me from editing the method during runtime, so I came up with this.
Obviously if you wanted to you could change it to a generic method (right term?) using type arguments. This also gets around the problem of lambdas in a method. Not sure if that applies to anonymous methods as well or not, but it is already separate so no big deal.
I don't know whether the reflection would have a performance hit or not.
private Predicate<ItemData> FindItemData(string search, string fieldName)
{
var field = typeof(ItemData).GetField(fieldName);
return delegate(ItemData item) { return (string)field.GetValue(item) == search; };
}
//in another method...
itemlist.Find(FindItemData(e.Row[2].ToString(), "ItemName"));

Deferred execution in C#

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.

Categories