Why doesn't Compile() run every time the method is called? - c#

Here is a code piece from MiscUtil library (by Jon Skeet & Marc Gravell):
static T Add<T>(T a, T b) {
//TODO: re-use delegate!
// declare the parameters
ParameterExpression paramA = Expression.Parameter(typeof(T), "a"),
paramB = Expression.Parameter(typeof(T), "b");
// add the parameters together
BinaryExpression body = Expression.Add(paramA, paramB);
// compile it
Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
// call it
return add(a,b);
}
It says below the code that:
Isn't this expensive?
Well, compiling the operators isn't trivial, but the static
constructor ensures that we only do this once for each signature.
What is the reason behind Func<T, T, T> doesn't get compiled every time Add<T>(T a, T b) method is called, but insted only gets compiled once?

There is only one static field per type, it's shared among them. This field is initialized just before first use (see this old documentation from MSDN).
If a static constructor (...) exists in the class, execution of the
static field initializers occurs immediately prior to executing that
static constructor. Otherwise, the static field initializers are
executed at an implementation-dependent time prior to the first use of
a static field of that class.
So when you declare and try to use SomeType<int,int> for the first time, its static field is initialized. When you declare and try to use SomeType<int,int> second time, there is no point in creating this field again. It already exists! It's managed internally by .NET environment. This is how language is designed.
Note that SomeType<int,int> and SomeType<int,long> are different types (different type arguments) and need separate static fields.

Here is a code piece from MiscUtil library (by Jon Skeet & Marc Gravell):
No. It says so below the code:
The actual code makes use of static classes and static constructors to cache the operators efficiently, and uses some shared code in ExpressionUtil to simplify the construction of the various Add, Subtract etc operators - but the theory is the same.
That should answer the question of how that code avoids calling Compile() each time: it doesn't, and the page does not claim it does.

Related

Difference between Task.FromResult<TResult> vs Task.FromResult? [duplicate]

So, I ran across an answer by Servy ( https://stackoverflow.com/a/15098242/496680 ) and some of his code does this:
public static int BinarySearch<TSource, TKey>(...)
for an extension method, but he calls it like this:
arr.BinarySearch(...)
I asked around and somebody metioned that its an implied generic type parameter.
I googled them but found no information on them.
I understand how generics work but I'm failing to understand how/when to use these.
Why does servy use them in his extention method?
Is there a more official name for these that I can search for?
Well, you left out the most important part that makes it all work. The type parameters can be inferred by the actual object parameters passed in.
For instance:
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
This extension method works on any IEnumerable class and will convert each item in the enumeration to another type based on the converter you provided. This is standard generics.
Now, there are many ways to call this method:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
All four variations call the same method and return the same result. Type inference works by looking at the parameters passed and automatically inferring their types based on what's being provided. In our examples above, it's able to determine that type T is of type int because we passed in an IEnumerable<int> into the parameter for IEnumerable<T>. It is also able to infer that type U is of type string because we passed in a Func matching the initial type of T with int and returning a string. So the Func<T, U> is filled in with our converter function of Func<int, string>.
From the inference above, it's a standard generic method at that point. Type inference and extension methods are nothing more than convenience/syntactic sugar. In fact, if you decompile the output you can see that extension methods are replaced with static calls and are usually defined with the type parameters explicitly filled out. (This varies based on your decompiler and the set options).
He uses a generic method in this case because it allows his method to work with any type contained within a Collection<T>. The generic method makes this very flexible, and usable for any type. He uses the type inferrence when calling the method because it simplifies the code at the call site.
The automatic handling is called Type Inferrence, and is covered, in detail, in the C# Language Specification, section 7.5.2: Type Inferrence. If you want to understand it in detail, I would recommend downloading the C# language specification.
The term I usually hear is 'type inference'.

C# lambda expressions without variable / parameter declaration?

What's it called when a method that takes a lambda expression as the parameter, such as Enumerable.Where, is invoked without actually declaring a variable or method parameter in the expression?
For example, I'm familiar with this lambda expression syntax:
public string GetDigits(string input)
{
return new String(input.Where(i => Char.IsDigit(i)).ToArray());
}
However, I was surprised to find out that this can also be written as:
public string GetDigits(string input)
{
return new String(input.Where(Char.IsDigit).ToArray());
}
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
Methods don't accept lambdas as parameters. They accept delegates as parameters. A lambda is just one way of creating a delegate.
Another way is supplying a method group, as is done in your second example, which can be converted to a delegate.
A similar way is to use the anonymous method feature. This was more or less replaced with lambdas when they were added though, so you don't see it much. Your example using that syntax would be:
Func<char, bool> predicate = delegate(char c) { return Char.IsDigit(c); };
Yet another way would be to create a delegate using Delegate.CreateDelegate. (This isn't something you see all that often though.)
A final way is to have a delegate variable that you got from somewhere else. (That somewhere else would have created the delegate using one of these other options.)
What's going on in that second snippet, where the Char.IsDigit() method is (apparently) being called with an implicit parameter? What is this syntax called?
It's not being called. That's the whole point. We're trying to create a delegate. A delegate is an object that keeps track of a method to be invoked, and an object that it should be invoked on. You can then invoke the delegate and it will call the method that was used to create it. So here you're not calling IsDigit, you're creating a delegate that is pointing to the IsDigit method, and that will call it whenever that delegate is invoked.
When you use a lambda you're creating a new method, possibly in a new class, (neither of which have a name you can refer to, but they'll have one at runtime) and the body of that anonymous method will call IsDigit. The lambda then resolves to a delegate pointing to that anonymous method, which maintains the semantics of the other example of having a method that when called, calls an anonymous method which, in its implementation, calls IsDigit. It's adding an extra layer of indirection (that may or may not just get optimized out at runtime) to accomplish the same thing.
The signature of Enumerable.Where is:
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
This:
input.Where(i => Char.IsDigit(i))
is equivalent to writing:
Func<char, bool> temp = i => Char.IsDigit(i);
input.Where(temp);
so it creates an anonymous function with a parameter i that calls Char.IsDigit.
This:
input.Where(Char.IsDigit)
is equivalent to
Func<char, bool> temp = Char.IsDigit;
input.Where(temp);
that is equivalent to:
Func<char, bool> temp = new Func<char, bool>(Char.IsDigit);
input.Where(temp);
so it creates a delegate to Char.IsDigit and then passes it to input.Where.
So the second one removes the "man-in-the-middle" (the anonymous function). In this particular case it is "legal" because the i parameter of the anonymous function is passed "as is" to Char.IsDigit. It would have been different if it was:
input.Where(i => !Char.IsDigit(i))
in this case, you can't remove the man-in-the-middle (the anonymous function).
There is no name for all of this (or you could call the first "creating and passing a delegate to an anonymous function" and the second "creating and passing a delegate created from a method group"... but they aren't beautiful catchphrases, they are more a description of what you are doing)
Because the compiler will implicitly cast the method group to a delegate if it finds a single method that matches the expected signature, in this case a delegate taking a single char as input and returning a bool.
Your Where expects a Func<char, bool>, which is a delegate for methods that take a char argument and return a bool. Anything that matches this delegate is a valid argument for this Where.
The lambda you wrote initially matches this delegate by type inference: the compiler expects that i is char, based on the generic parameter of the enumerable source - and infers the return type as bool, because that's what the method call expression inside the lambda would return.
The Char.IsDigit method itself also matches this. Thus, referencing the method is another valid way of expressing the same thing. This is called a method group.
The semantic equivalence of these two possible arguments for Where also makes sense if you consider that for every lambda expression, the compiler generates an anonymous method and then passes that anonymous method where the delegate was expected.
To illustrate this, consider your original snippet:
Where(i => Char.IsDigit(i))
The above gets lowered by the compiler to:
bool AnAnonymousMethod(char i)
{
return Char.IsDigit(i);
}
and then:
Where(AnAnonymousMethod)
As you can see, the lambda syntax (in cases where you don't have captured variables, like here) is just syntactic sugar for writing an anonymous method and then using the method group of this newly written method as the argument wherever a compatible delegate is expected.

What are implied generic type parameters

So, I ran across an answer by Servy ( https://stackoverflow.com/a/15098242/496680 ) and some of his code does this:
public static int BinarySearch<TSource, TKey>(...)
for an extension method, but he calls it like this:
arr.BinarySearch(...)
I asked around and somebody metioned that its an implied generic type parameter.
I googled them but found no information on them.
I understand how generics work but I'm failing to understand how/when to use these.
Why does servy use them in his extention method?
Is there a more official name for these that I can search for?
Well, you left out the most important part that makes it all work. The type parameters can be inferred by the actual object parameters passed in.
For instance:
static class Extensions {
internal static IEnumerable<U> Test<T, U>(
this IEnumerable<T> items,
Func<T, U> converter) {
foreach (T item in items) {
yield return converter(item);
}
}
}
This extension method works on any IEnumerable class and will convert each item in the enumeration to another type based on the converter you provided. This is standard generics.
Now, there are many ways to call this method:
IEnumerable<int> values = Enumerable.Range<int>(1, 10);
Func<int, string> converter = i => i.ToString("0.00");
// Variation 1, explicit calling
IEnumerable<string> results1 = Extensions.Test<int, string>(values, converter);
// Variation 2, explicit calling with type inference
IEnumerable<string> results2 = Extensions.Test(values, converter);
// Variation 3, extension method calling, still providing explicit types
IEnumerable<string> results3 = values.Test<int, string>(converter);
// Variation 4, extension method with type inference
IEnumerable<string> results4 = values.Test(converter);
All four variations call the same method and return the same result. Type inference works by looking at the parameters passed and automatically inferring their types based on what's being provided. In our examples above, it's able to determine that type T is of type int because we passed in an IEnumerable<int> into the parameter for IEnumerable<T>. It is also able to infer that type U is of type string because we passed in a Func matching the initial type of T with int and returning a string. So the Func<T, U> is filled in with our converter function of Func<int, string>.
From the inference above, it's a standard generic method at that point. Type inference and extension methods are nothing more than convenience/syntactic sugar. In fact, if you decompile the output you can see that extension methods are replaced with static calls and are usually defined with the type parameters explicitly filled out. (This varies based on your decompiler and the set options).
He uses a generic method in this case because it allows his method to work with any type contained within a Collection<T>. The generic method makes this very flexible, and usable for any type. He uses the type inferrence when calling the method because it simplifies the code at the call site.
The automatic handling is called Type Inferrence, and is covered, in detail, in the C# Language Specification, section 7.5.2: Type Inferrence. If you want to understand it in detail, I would recommend downloading the C# language specification.
The term I usually hear is 'type inference'.

When creating a fluent api, how do they chained methods get context from previous methods?

I'm looking at this open source project, and the fluent api looks like:
baseEngine.For<Foo1>()
.Setup(f => f.Value)
.MustEqual(1);
Then MustEqual method's parameter list it:
public static M MustEqual<M, T, R>(this IMustPassRule<M, T, R> mpr, R value)
{
return mpr.MustPassRule(new EqualRule<R>(value));
}
for more details: http://rulesengine.codeplex.com/SourceControl/changeset/view/9077#137411
So what I'm trying to get at is, the call to MustEqual is being passed only a single arguement, since it is fluent, is it somehow implicitly picking up other required parameters from the previously chained calls?
The state gets stored in the object itself by those previous methods, if necessary.
You are looking at an Extension Method.
Extension Methods allow static methods to be invoked with instance method syntax. For instance,
something.MustEqual(1);
is equivalent to
RulesHelper.MustEqual(something, 1);
A nice example can be found in LINQ
The IEnumerable<T>.OrderBy returns an IOrderedEnumerable<T>
This second interface keeps track of the order so the IOrderedEnumerable<T>.ThenBy is able to do a sub-sort. To make things smooth the interface derives from IEnumerable<T>

Why Func<T,bool> instead of Predicate<T>?

This is just a curiosity question I was wondering if anyone had a good answer to:
In the .NET Framework Class Library we have for example these two methods:
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate
)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Why do they use Func<TSource, bool> instead of Predicate<TSource>? Seems like the Predicate<TSource> is only used by List<T> and Array<T>, while Func<TSource, bool> is used by pretty much all Queryable and Enumerable methods and extension methods... what's up with that?
While Predicate has been introduced at the same time that List<T> and Array<T>, in .net 2.0, the different Func and Action variants come from .net 3.5.
So those Func predicates are used mainly for consistency in the LINQ operators. As of .net 3.5, about using Func<T> and Action<T> the guideline states:
Do use the new LINQ types Func<> and
Expression<> instead of custom
delegates and predicates
I've wondered this before. I like the Predicate<T> delegate - it's nice and descriptive. However, you need to consider the overloads of Where:
Where<T>(IEnumerable<T>, Func<T, bool>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
That allows you to filter based on the index of the entry as well. That's nice and consistent, whereas:
Where<T>(IEnumerable<T>, Predicate<T>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
wouldn't be.
Surely the actual reason for using Func instead of a specific delegate is that C# treats separately declared delegates as totally different types.
Even though Func<int, bool> and Predicate<int> both have identical argument and return types, they are not assignment-compatible. So if every library declared its own delegate type for each delegate pattern, those libraries would not be able to interoperate unless the user inserts "bridging" delegates to perform conversions.
// declare two delegate types, completely identical but different names:
public delegate void ExceptionHandler1(Exception x);
public delegate void ExceptionHandler2(Exception x);
// a method that is compatible with either of them:
public static void MyExceptionHandler(Exception x)
{
Console.WriteLine(x.Message);
}
static void Main(string[] args)
{
// can assign any method having the right pattern
ExceptionHandler1 x1 = MyExceptionHandler;
// and yet cannot assign a delegate with identical declaration!
ExceptionHandler2 x2 = x1; // error at compile time
}
By encouraging everyone to use Func, Microsoft is hoping that this will alleviate the problem of incompatible delegate types. Everyone's delegates will play nicely together, because they will just be matched up based on their parameter/return types.
It doesn't solve all problems, because Func (and Action) can't have out or ref parameters, but those are less commonly used.
Update: in the comments Svish says:
Still, switching a parameter type from
Func to Predicate and
back, doesn't seem to make any
difference? At least it still compiles
without any problems.
Yes, as long as your program only assigns methods to delegates, as in the first line of my Main function. The compiler silently generates code to new a delegate object that forwards on to the method. So in my Main function, I could change x1 to be of type ExceptionHandler2 without causing a problem.
However, on the second line I try to assign the first delegate to another delegate. Even thought that 2nd delegate type has exactly the same parameter and return types, the compiler gives error CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'.
Maybe this will make it clearer:
public static bool IsNegative(int x)
{
return x < 0;
}
static void Main(string[] args)
{
Predicate<int> p = IsNegative;
Func<int, bool> f = IsNegative;
p = f; // Not allowed
}
My method IsNegative is a perfectly good thing to assign to the p and f variables, as long as I do so directly. But then I can't assign one of those variables to the other.
The advice (in 3.5 and above) is to use the Action<...> and Func<...> - for the "why?" - one advantage is that "Predicate<T>" is only meaningful if you know what "predicate" means - otherwise you need to look at object-browser (etc) to find the signatute.
Conversely Func<T,bool> follows a standard pattern; I can immediately tell that this is a function that takes a T and returns a bool - don't need to understand any terminology - just apply my truth test.
For "predicate" this might have been OK, but I appreciate the attempt to standardise. It also allows a lot of parity with the related methods in that area.

Categories