Assign a variable the result of dynamic function call in C# - c#

In JavaScript I can assign a value to a variable by dynamically creating a function. Such as
var name = (function () { name="bob"; return name; }());
I'm fairly certain that with C# 4.0 the same type of thing is possible. Could someone show me the syntax of how the same line above would look in C#?
Also, if you could jog my memory on what the proper term for creating this type of dynamic function is, it would be much appreciated!
Thanks for your help!
PS: It's likely this question has been asked before, but since I was unclear on the nomenclature I may have missed finding it. If that's the case, I apologize!

You can use anonymous methods:
Func<string> anonymousFunction = () => { string name = "bob"; return name; };
string myName = anonymousFunction();
The syntax on the first line is a lambda, which is the C#3.0 and above way of declaring anonymous methods. The above function takes no arguments, but there's nothing stopping you from including them as well:
Func<string, string> makeUppercase = x => x.ToUpper();
string upperCase = makeUppercase("lowercase");
Note that since there is only one parameter, you can elide the brackets around it. As well, since the entire method is a single return statement, you can elide both the brace brackets as well as the return statement itself.
This type of lambda is very common when using the LINQ extension methods, since many of them require a single-argument method that returns a value:
var numbers = new List<int>() { 1, 2, 3, 4 };
var divisibleByTwo = numbers.Where(num => num % 2 == 0);
To answer your actual question, that syntax is not valid in C#. If you try this:
string output = (x => x.ToUpper())("lowercase");
You'll get an error message saying "Method name expected." You have to assign the anonymous method to a delegate first.

Generally what you want to look into are Func/Actions:
http://msdn.microsoft.com/en-us/library/bb549151.aspx
http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
And for that matter, lambda expressions:
http://msdn.microsoft.com/en-us/library/bb397687.aspx

Related

Is there a typed way to declare a method name in C#

I have some reflection code and I would love to have a way of binding the method names to types instead of declaring through strings.
I have this interface:
interface IDoStuff<T> {
void Do(T stuff);
}
Then I have this code:
object stuff = GotThisFromSomewhereElse();
object doer = GotThisFromSomewhereElseAlso();
var doMethodInfo = doer.GetType().GetMethod("Do");
doMethodInfo.Invoke(doer, new[] { stuff });
The problem is that I can't simply do a safe cast and call it because it's generic and I don't actually know what type T is.
This works fine but when I rename the method I have to go update this, I'm not overly concerned as I have tests to confirm all of this works which protects against not knowing it changed.
It's just really ugly and I was curious if there is some slick way to have this typed and thus will get renamed by ReSharper if I change it.
I'd really like something like:
object stuff = GotThisFromSomewhereElse();
object doer = GotThisFromSomewhereElseAlso();
var doMethodInfo = doer.GetType().Methods.Do;
doMethodInfo.Invoke(doer, new[] { stuff });
Thanks in advance and please let me know if this is something that is possible in C#.
Starting with C# 6, you'll be able to avoid the magic string using the new nameof statement:
IDoStuff<object> dummy = null; // don't need a valid instance.
string methodName = nameof(dummy.Do) // yay! no magic strings.
EDIT: #31eee384 pointed out in the comments that the above can be further simplified like this:
string methodName = nameof(IDoStuff<object>.Do);
About the new nameof statement, the documentation has this to say, which seems very much in line with what OP is trying to accomplish:
you often want to capture the string name of a method. Using nameof helps keep your code valid when renaming definitions. Before you had to use string literals to refer to definitions, which is brittle when renaming code elements because tools do not know to check these string literals.
Before C# 6, it's also possible to avoid magic strings by using expressions, but it's a little clunkier. Here is an example that would work in your case.
First, you write the following extension method:
public static string GetMethodName<T>(this T instance, Expression<Action<T>> methodExpression)
{
if (methodExpression.Body is MethodCallExpression)
{
return ((MethodCallExpression)methodExpression.Body).Method.Name;
}
else
{
throw new ArgumentException(string.Format("Invalid method expression: {0}", methodExpression.Body));
}
}
And then you can use it like this:
IDoStuff<object> dummy = null; // don't need a valid instance.
string methodName = dummy.GetMethodName(t => t.Do(null)); // yay! still no magic strings.
Create generic method DoIt:
private void DoIt<T>(T stuff, IDoStuff<T> doer) {
doer.Do(stuff);
}
and call it:
DoIt(GotThisFromSomewhereElse(), GotThisFromSomewhereElseAlso());
Of course, GotThisFromSomewhereElseAlso and GotThisFromSomewhereElse should be generics as well.

How can I use System.Func?

I have trouble using System.Func.
public Func<int> OnCreated=new Func<int>(int ASD){ Debug.Log (ASD); };
Is this the proper way to use it? I want to make a dynamic function that can be called. Also can the System.Func be serialized via XML?
Maybe you're looking for Action<> instead?
Action<int> myAction = myIntParam => Debug.Log(myIntParam);
myAction(myInteger);
If you want to take an input parameter, and return something, you should use Func<>
Func<int, int> myFunc = myIntParam => {
Debug.Log(myIntParam);
return 5;
};
int five = myFunc(myInteger);
Also, if you want to serialize/deserialize, you need to take it one step further. Namely, by def Func does not really have any meaningful information for it to be serialized, you should wrap it in Expression. You can get started by googling for "C# serialize expression", eg: https://expressiontree.codeplex.com
Just like any other thing in .NET Func is an Object. Func is an object of type Delegate.You can serialize/deserialize any serializable object. Func returns a value and can take up to 16 parameters.
The way you would use it is like this :
Func<int> w = new Func<int>(() => { return 1; });
You should first be familiar with the use of delegates. Check this : when & why to use delegates?
P.S Serializing delegates is a risky thing to do since they are pointers to functions that are inside your program.|
You can check how you can do the serialization over here : Could we save delegates in a file (C#)

Why can't an anonymous method be assigned to var?

I have the following code:
Func<string, bool> comparer = delegate(string value) {
return value != "0";
};
However, the following does not compile:
var comparer = delegate(string value) {
return value != "0";
};
Why can't the compiler figure out it is a Func<string, bool>? It takes one string parameter, and returns a boolean. Instead, it gives me the error:
Cannot assign anonymous method to an
implicitly-typed local variable.
I have one guess and that is if the var version compiled, it would lack consistency if I had the following:
var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
return false;
};
The above wouldn't make sense since Func<> allows only up to 4 arguments (in .NET 3.5, which is what I am using). Perhaps someone could clarify the problem. Thanks.
UPDATE: This answer was written over ten years ago and should be considered to be of historical interest; in C# 10 the compiler will infer some delegate types.
Others have already pointed out that there are infinitely many possible delegate types that you could have meant; what is so special about Func that it deserves to be the default instead of Predicate or Action or any other possibility? And, for lambdas, why is it obvious that the intention is to choose the delegate form, rather than the expression tree form?
But we could say that Func is special, and that the inferred type of a lambda or anonymous method is Func of something. We'd still have all kinds of problems. What types would you like to be inferred for the following cases?
var x1 = (ref int y)=>123;
There is no Func<T> type that takes a ref anything.
var x2 = y=>123;
We don't know the type of the formal parameter, though we do know the return. (Or do we? Is the return int? long? short? byte?)
var x3 = (int y)=>null;
We don't know the return type, but it can't be void. The return type could be any reference type or any nullable value type.
var x4 = (int y)=>{ throw new Exception(); }
Again, we don't know the return type, and this time it can be void.
var x5 = (int y)=> q += y;
Is that intended to be a void-returning statement lambda or something that returns the value that was assigned to q? Both are legal; which should we choose?
Now, you might say, well, just don't support any of those features. Just support "normal" cases where the types can be worked out. That doesn't help. How does that make my life easier? If the feature works sometimes and fails sometimes then I still have to write the code to detect all of those failure situations and give a meaningful error message for each. We still have to specify all that behaviour, document it, write tests for it, and so on. This is a very expensive feature that saves the user maybe half a dozen keystrokes. We have better ways to add value to the language than spending a lot of time writing test cases for a feature that doesn't work half the time and doesn't provide hardly any benefit in cases where it does work.
The situation where it is actually useful is:
var xAnon = (int y)=>new { Y = y };
because there is no "speakable" type for that thing. But we have this problem all the time, and we just use method type inference to deduce the type:
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
and now method type inference works out what the func type is.
Only Eric Lippert knows for sure, but I think it's because the signature of the delegate type doesn't uniquely determine the type.
Consider your example:
var comparer = delegate(string value) { return value != "0"; };
Here are two possible inferences for what the var should be:
Predicate<string> comparer = delegate(string value) { return value != "0"; }; // okay
Func<string, bool> comparer = delegate(string value) { return value != "0"; }; // also okay
Which one should the compiler infer? There's no good reason to choose one or the other. And although a Predicate<T> is functionally equivalent to a Func<T, bool>, they are still different types at the level of the .NET type system. The compiler therefore cannot unambiguously resolve the delegate type, and must fail the type inference.
Eric Lippert has an old post about it where he says
And in fact the C# 2.0 specification
calls this out. Method group
expressions and anonymous method
expressions are typeless expressions
in C# 2.0, and lambda expressions join
them in C# 3.0. Therefore it is
illegal for them to appear "naked" on
the right hand side of an implicit
declaration.
Different delegates are considered different types. e.g., Action is different than MethodInvoker, and an instance of Action can't be assigned to a variable of type MethodInvoker.
So, given an anonymous delegate (or lambda) like () => {}, is it an Action or a MethodInvoker? The compiler can't tell.
Similarly, if I declare a delegate type taking a string argument and returning a bool, how would the compiler know you really wanted a Func<string, bool> instead of my delegate type? It can't infer the delegate type.
The following points are from the MSDN regarding Implicitly Typed Local Variables:
var can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.
The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement.
It is important to understand that the var keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.
MSDN Reference: Implicitly Typed Local Variables
Considering the following regarding Anonymous Methods:
Anonymous methods enable you to omit the parameter list.
MSDN Reference: Anonymous Methods
I would suspect that since the anonymous method may actually have different method signatures, the compiler is unable to properly infer what the most appropriate type to assign would be.
My post doesn't answer the actual question, but it does answer the underlying question of :
"How do I avoid having to type out some fugly type like Func<string, string, int, CustomInputType, bool, ReturnType>?" [1]
Being the lazy/hacky programmer that I am, I experimented with using Func<dynamic, object> - which takes a single input parameter and returns an object.
For multiple arguments, you can use it like so:
dynamic myParams = new ExpandoObject();
myParams.arg0 = "whatever";
myParams.arg1 = 3;
Func<dynamic, object> y = (dynObj) =>
{
return dynObj.arg0.ToUpper() + (dynObj.arg1 * 45); //screw type casting, amirite?
};
Console.WriteLine(y(myParams));
Tip: You can use Action<dynamic> if you don't need to return an object.
Yeah I know it probably goes against your programming principles, but this makes sense to me and probably some Python coders.
I'm pretty novice at delegates... just wanted to share what I learned.
[1] This assumes that you aren't calling a method that requires a predefined Func as a parameter, in which case, you'll have to type that fugly string :/
Other answers were correct at the time they were written, but starting from C# 10.0 (from 2021), the compiler can infer a suitable delegate type (like some Func<...>, Action<...> or generated delegate type) in such cases.
See C# 10 Features - Lambda improvements.
var comparer = delegate(string value) {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
Of course the more usual syntax is to us =>, so:
var comparer = (string value) => {
return value != "0";
}; // OK in C# 10.0, picks 'Func<string, bool>' in this case
How is about that?
var item = new
{
toolisn = 100,
LangId = "ENG",
toolPath = (Func<int, string, string>) delegate(int toolisn, string LangId)
{
var path = "/Content/Tool_" + toolisn + "_" + LangId + "/story.html";
return File.Exists(Server.MapPath(path)) ? "<a style=\"vertical-align:super\" href=\"" + path + "\" target=\"_blank\">execute example</a> " : "";
}
};
string result = item.toolPath(item.toolisn, item.LangId);

What is actually happening with IQueryable.Where()?

This is is returning a boolean based on whether or not there are some matching IDs.
from t in getAll
select new Result
{
...
bool DetailsAvailable =
(db.SaveTrackings.Where(s => s.BundleID == t.bundleID
&& s.UserID == t.userID)
.Count() > 0) ? true : false;
}
This is what I think understand: .Where() is returning all the entries with the matching IDs and then the .Count() is just seeing how many are there. I only feel like I half understand what we need s for.
I know what to expect from this code since it's been in use I just don't understand how it works and some of the documentation from MSDN is using some terminology that is confusing me.
All lambda expressions use the lambda
operator =>, which is read as "goes
to". The left side of the lambda
operator specifies the input
parameters (if any) and the right side
holds the expression or statement
block. The lambda expression x => x *
x is read "x goes to x times x."
So how am I suppose to understand what my code means based on this, .Where(s "goes to" s.BundleID == t.BundleID...) so what's happening here? What does "goes to" mean? Is it comparing every ID in s to everyone one available in t? How do I understand why it's called "goes to" and what exactly is happening?
And then it gets more confusing...
The => operator has the same
precedence as assignment (=) and is
right-associative.
Lambdas are used in method-based LINQ
queries as arguments to standard query
operator methods such as Where.
When you use method-based syntax to
call the Where method in the
Enumerable class (as you do in LINQ to
Objects and LINQ to XML) the parameter
is a delegate type System.Func. A lambda expression is the
most convenient way to create that
delegate.
What is a delegate type System.Func<T, TResult> and how is it created with this "goes to" operator?
I can't just use code because I know that it's working, I need to understand how/why.
Maybe it would help to see this function implemented by hand:
using System;
using System.Collections.Generic;
namespace CSharpSandbox
{
class Program
{
static IEnumerable<T> Where<T>(IEnumerable<T> input, Func<T, bool> predicate)
{
foreach (T item in input)
{
if (predicate(item))
yield return item;
}
}
static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> evens = Where(numbers, n => n % 2 == 0);
foreach (int even in evens)
{
Console.WriteLine(even);
}
}
}
}
The construct name => someEvaluation creates an anonymous function consisting of the following parts:
name is simply the name of a parameter, its type is inferred from its usage. You need a name so you can refer to the argument passed in the function.
=> is the start of your anonymous functions body, the scope of the body is a single expression.
someEvaluation is the body of your anonymous function composed of a single expression.
In our case, Func<T, bool> defines a function which takes a single parameter of type T and returns an output of type bool. (If we had used Func<T, U, bool>, we'd take two inputs of type T and U and return a bool. The last type parameter in the Func definition is the return value.)
You can invoke an instance of Func exactly as you invoke any other function. If the func takes params, you pass them in as expected, your parameters are bound to the variable names you defined. When you invoke the function, control flow will jump inside your function and evaluate its results.
In principle, you don't need to create a Func anonymously. You can pass in any function which has a compatible type signature, such as:
static bool IsEven(int n)
{
return n % 2 == 0;
}
static void Main(string[] args)
{
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> evens = Where(numbers, IsEven);
foreach (int even in evens)
{
Console.WriteLine(even);
}
}
This program produces the same output. In fact, behind the scenes, the syntax name => expression is syntax sugar; when it gets compiled, C# will produce a produce a private function with a hidden name and convert it to the format above.
If it helps, think of s as a variable of type SaveTracking. It's iterating over each s in your collection/table, and testing the value of its BundleID.
The t is same idea - it's like it's iterating through all the return collection from the getAll.
It's like the SQL pseudocode:
SELECT * FROM SaveTracking INNER JOIN GetAll
ON BundleID AND UserID
For a deeper technical description of what's going on with lambda expressions, check out Jon Skeet's book C# In Depth. Chapter 9 , p 230. I found this book very helpful.
Lambda expressions are just a way to shorten the code but it does exactly the same things as declaring a method that corresponds to the delegate type System.Func<T, TResult>
I believe that C# converts your lamba to a method in the background when you compile and it looks like this :
bool LambdaExpression(YourType s)
{
return s.BundleID == t.bundleID && s.UserID == t.userID;
}

C# Generic Generics (A Serious Question)

In C# I am trying to write code where I would be creating a Func delegate which is in itself generic. For example the following (non-Generic) delegate is returning an arbitrary string:
Func<string> getString = () => "Hello!";
I on the other hand want to create a generic which acts similarly to generic methods. For example if I want a generic Func to return default(T) for a type T. I would imagine that I write code as follows:
Func<T><T> getDefaultObject = <T>() => default(T);
Then I would use it as
getDefaultObject<string>() which would return null and if I were to write getDefaultObject<int>() would return 0.
This question is not merely an academic excercise. I have found numerous places where I could have used this but I cannot get the syntax right. Is this possible? Are there any libraries which provide this sort of functionality?
Well you can't overload anything based only on the return value, so this includes variables.
You can however get rid of that lambda expression and write a real function:
T getDefaultObject<T>() { return default(T); }
and then you call it exactly like you want:
int i=getDefaultObject<int>(); // i=0
string s=getDefaultObject<string>(); // s=null
Though one might find practical workarounds like Stephen Cleary's
Func<T> CreateGetDefaultObject<T>() { return () => default(T); }
where you can specify the generics directly, this is a quite interesting problem from a theoretical point that cannot be solved by C#'s current type system.
A type which, as you call it, is in itself generic, is referred to as a higher-rank type.
Consider the following example (pseudo-C#):
Tuple<int[], string[]> Test(Func<?> f) {
return (f(1), f("Hello"));
}
In your proposed system, a call could look like that:
Test(x => new[] { x }); // Returns ({ 1 }, { "Hello" })
But the question is: How do we type the function Test and it's argument f?
Apparently, f maps every type T to an array T[] of this type. So maybe?
Tuple<int[], string[]> Test<T>(Func<T, T[]> f) {
return (f(1), f("Hello"));
}
But this doesn't work. We can't parameterize Test with any particular T, since f should can be applied to all types T. At this point, C#'s type system can't go further.
What we needed was a notation like
Tuple<int[], string[]> Test(forall T : Func<T, T[]> f) {
return (f(1), f("Hello"));
}
In your case, you could type
forall T : Func<T> getDefaultValue = ...
The only language I know that supports this kind of generics is Haskell:
test :: (forall t . t -> [t]) -> ([Int], [String])
test f = (f 1, f "hello")
See this Haskellwiki entry on polymorphism about this forall notation.
This isn't possible, since a delegate instance in C# cannot have generic parameters. The closest you can get is to pass the type object as a regular parameter and use reflection. :(
In many cases, casting to dynamic helps remove the pain of reflection, but dynamic doesn't help when creating new instances, such as your example.
You can't do this, because generic type parameters have to be known at runtime. You have to use the activator class:
Object o = Activator.CreateInstance(typeof(StringBuilder));
which will do exactly what you want to. You can write it as the following:
public T Default<T>()
{
return (T)Activator.CreateInstance(typeof(T));
}
Edit
Blindy's solution is better.

Categories

Resources