Overhead of delegate definition inside of another method - c#

I'm curious to understand what's happening behind the scenes in a situation like this:
public static void OuterMethod() {
// some random code
var a = 42;
var b = "meaning of life";
Func<string, object> factory = (aString) {
// do something with a and b
return "Hello World";
};
// some more random code
factory("My string");
}
I'm particularly interested in cases where OuterMethod is called very often. In my case it's the MVC request pipeline where OuterMethod is called once for each request.
Am I incurring a lot overhead by having to build factory each time the method is called? I could easily move the Func outside of OuterMethod into its own static method however in my actual scenario because it is defined inside I have access to a lot of variables I need to do my calculation that I would otherwise need to include in the signature of a method defined outside. Maybe this is just a micro optimization but I would like to better understand how the compiler treats these kinds of statements.

The actual lambda is going to result in a new named method (you just don't know what that name is) being created at compile time (the exact semantics will vary based on some of the specifics).
The only work being done on each invocation of the method is the creation of a new delegate object that has its own pointer to the same named method. If constructing that one object instance is really too much for you (hint: its not) then you could save that work by extracting the delegate out of the method.

Related

Datatype of Methods

Question
How does a delegate store a reference to a function? The source code appears to refer to it as an Object, and the manner in which it invokes the method seems redacted from the source code. Can anyone explain how C# is handling this?
Original Post
It seems I'm constantly fighting the abstractions C# imposes on its programmers. One that's been irking me is the obfuscation of Functions/Methods. As I understand it, all methods are in fact anonymous methods assigned to properties of a class. This is the reason why no function is prefixed by a datatype. For example...
void foo() { ... }
... would be written in Javascript as...
Function foo = function():void { ... };
In my experience, Anonymous functions are typically bad form, but here it's replete throughout the language standard. Because you cannot define a function with its datatype (and apparently the implication/handling is assumed by the compiler), how does one store a reference to a method if the type is never declared?
I'm trying very hard to avoid Delegates and its variants (Action & Func), both because...
it is another abstraction from what's actually happening
the unnecessary overhead required to instantiate these classes (which in turn carry their own pointers to the methods being called).
Looking at the source code for the Delegate.cs, it appears to refer to the reference of a function as simply Object (see lines 23-25).
If these really are objects, how are we calling them? According to the delegate.cs trail, it dead-ends on the following path:
Delegate.cs:DynamicInvoke() > DynamicInvokeImpl() > methodinfo.cs:UnsafeInvoke() > UnsafeInvokeInternal() > RuntimeMethodHandle.InvokeMethod() > runtimehandles.cs:InvokeMethod()
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
This really doesn't explain how its invoked if indeed the method is an object. It feels as though this is not code at all, and the actual code called has been redacted from source repository.
Your help is appreciated.
Response to Previous Comments
#Amy: I gave an example immediately after that statement to explain what I meant. If a function were prefixed by a datatype, you could write a true anonymous function, and store it as a property to an Object such as:
private Dictionary<string, Function> ops = new Dictionary<string, Function> {
{"foo", int (int a, int b) { return a + b } }
};
As it stands, C# doesn't allow you to write true anonymous functions, and walls that functionality off behind Delegates and Lambda expressions.
#500 Internal server error: I already explained what I was trying to do. I even bolded it. You assume there's any ulterior motive here; I'm simply trying to understand how C# stores a reference to a method. I even provided links to the source code so that others could read the code for themselves and help answer the question.
#Dialecticus: Obviously if I already found the typical answer on Google, the only other place to find the answer I'm looking for would be here. I realize this is outside the knowledge of most C# developers, and that's why I've provided the source code links. You don't have to reply if you don't know the answer.
While I'm not fully understanding your insights about "true anonymous functions", "not prefixed by a data type" etc, I can explain you how applications written in C# call methods.
First of all, there is no such a thing "function" in C#. Each and every executable entity in C# is in fact a method, that means, it belongs to a class. Even if you define lambdas or anonymous functions like this:
collection.Where(item => item > 0);
the C# compiler creates a compiler-generated class behind the scenes and puts the lambda body return item > 0 into a compiler-generated method.
So assuming you have this code:
class Example
{
public static void StaticMethod() { }
public void InstanceMethod() { }
public Action Property { get; } = () => { };
}
static class Program
{
static void Main()
{
Example.StaticMethod();
var ex = new Example();
ex.InstanceMethod();
ex.Property();
}
}
The C# compiler will create an IL code out of that. The IL code is not executable right away, it needs to be run in a virtual machine.
The IL code will contain a class Example with two methods (actually, four - a default constructor and the property getter method will be automatically generated) and a compiler-generated class containing a method whose body is the body of the lambda expression.
The IL code of Main will look like this (simplified):
call void Example::StaticMethod()
newobj instance void Example::.ctor()
callvirt instance void Example::InstanceMethod()
callvirt instance class [mscorlib]System.Action Example::get_Prop()
callvirt instance void [mscorlib]System.Action::Invoke()
Notice those call and callvirt instructions: these are method calls.
To actually execute the called methods, their IL code needs to be compiled into machine code (CPU instructions). This occurs in the virtual machine called .NET Runtime. There are several of them like .NET Framework, .NET Core, Mono etc.
A .NET Runtime contains a JIT (just-in-time) compiler. It converts the IL code to the actually executable code during the execution of your program.
When the .NET Runtime first encounters the IL code "call method StaticMethod from class Example", it first looks in the internal cache of already compiled methods. When there are no matches (which means this is the first call of that method), the Runtime asks the JIT compiler to create such a compiled-and-ready-to-run method using the IL code. The IL code is converted into a sequence of CPU operations and stored in the process' memory. A pointer to that compiled code is stored in the cache for future reuse.
This all will happen behind the call or callvirt IL instructions (again, simplified).
Once this happened, the Runtime is ready to execute the method. The CPU gets the compiled code's first operation address as the next operation to execute and goes on until the code returns. Then, the Runtime takes over again and proceeds with next IL instructions.
The DynamicInvoke method of the delegates does the same thing: it instructs the Runtime to call a method (after some additional arguments checks etc). The "dead end" you mention RuntimeMethodHandle.InvokeMethod is an intrinsic call to the Runtime directly. The parameters of this method are:
object target - the object on which the delegate invokes the instance method (this parameter).
object[] arguments - the arguments to pass to the method.
Signature sig - the actual method to call, Signature is an internal class that provides the connection between the managed IL code and native executable code.
bool constructor - true if this is a constructor call.
So in summary, methods are not represented as objects in C# (while you of course can have a delegate instance that is an object, but it doesn't represent the executable method, it rather provides an invokable reference to it).
Methods are called by the Runtime, the JIT compiler makes the methods executable.
You cannot define a global "function" outside of classes in C#. You could get a direct native pointer to the compiled (jitted) method code and probably even call it manually by directly manipulating own process' memory. But why?
You clearly misunderstand main differences between script languages, C/C++ and C#.
I guess the main difficulty is that there is no such thing as a function in C#. At all.
C#7 introduced the new feature "a local function", but that is not what a function in JS is.
All pieces of code are methods.
That name is intentionally different from function or a procedure to emphasize the fact that all executable code in C# belongs to a class.
Anonymous methods and lambdas are just a syntax sugar.
A compiler will generate a real method in the same (or a nested) class, where the method with anonymous method declaration belongs to.
This simple article explains it. You can take the examples, compile them and check the generated IL code yourself.
So all the methods (anonymous or not) do belong to a class. It's impossible to answer your updated question, besides saying It does not store a reference to a function, as there is no such thing in C#.
How does one store a reference to a method?
Depending on what you mean by reference, it can be either
An instance of MethodInfo class, used to reference reflection information for a method,
RuntimeMethodHandle (obtainable via RuntimeMethodInfo.MethodHandle) stores a real memory pointer to a JITed method code
A delegate, that is very different from just a memory pointer, but logically could be used to "pass a method reference to another method" .
I believe you are looking for the MethodInfo option, it has a MethodInfo.Invoke method which is very much alike Function..apply function in JS. You have already seen in the Delegate source code how that class is used.
If by "reference" you mean the C-style function pointer, it is in RuntimeMethodHandle struct. You should never use it without solid understanding how a particular .Net platform implementation and a C# compiler work.
Hopefully it clarifies things a bit.
A delegate is simply a pointer(memory location to jump to) to a method with the specified parameters and return type. Any Method that matches the signature(Parameters and return type) is eligible to fulfill the role, irrespective of the defined object. Anonymous simply means the delegate is not named.
Most times the type is implied(if it is not you will get a compiler error):
C# is a strongly typed language. That means every expression (including delegates) MUST have a return type(including void) as well as strongly typed parameters(if any). Generics were created to permit explicit types to be used within general contexts, such as Lists.
To put it another way, delegates are the type-safe managed version of C++ callbacks.
Delegates are helpful in eliminating switch statements by allowing the code to jump to the proper handler without testing any conditions.
A delegate is similar to a Closure in Javascript terminology.
In your response to Amy, you are attempting to equate a loosely typed language like JS, and a strongly typed language C#. In C# it is not possible to pass an arbitrary(loosely-typed) function anywhere. Lambdas and delegates are the only way to guarantee type safety.
I would recommend trying F#, if you are looking to pass functions around.
EDIT:
If you are trying to mimic the behavior of Javascipt, I would try looking at using inheritance through Interfaces. I can mimic multiple inheritance, and be type safe at the same time. But, be aware that it cannot fully supplant Javascript's dependency injection model.
As you probably found out C# doesn't have the concept of a function as in your JavaScript example.
C# is a statically typed language and the only way you can use function pointers is by using the built in types (Func,Action) or custom delegates.(I'm talking about safe,strongly typed pointers)
Javascript is a dynamic language that's why you can do what you describe
If you are willing to lose type safety, you can use the "dynamic" features of C# or refection to achieve what you want like in the following examples (Don't do this,use Func/Action)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace ConsoleApp1
{
class Program
{
private static Dictionary<string, Func<int, int, int>> FuncOps = new Dictionary<string, Func<int, int, int>>
{
{"add", (a, b) => a + b},
{"subtract", (a, b) => a - b}
};
//There are no anonymous delegates
//private static Dictionary<string, delegate> DelecateOps = new Dictionary<string, delegate>
//{
// {"add", delegate {} }
//};
private static Dictionary<string, dynamic> DynamicOps = new Dictionary<string, dynamic>
{
{"add", new Func<int, int, int>((a, b) => a + b)},
{"subtract", new Func<int, int, int>((a, b) => a - b)},
{"inverse", new Func<int, int>((a) => -a )} //Can't do this with Func
};
private static Dictionary<string, MethodInfo> ReflectionOps = new Dictionary<string, MethodInfo>
{
{"abs", typeof(Math).GetMethods().Single(m => m.Name == "Abs" && m.ReturnParameter.ParameterType == typeof(int))}
};
static void Main(string[] args)
{
Console.WriteLine(FuncOps["add"](3, 2));//5
Console.WriteLine(FuncOps["subtract"](3, 2));//1
Console.WriteLine(DynamicOps["add"](3, 2));//5
Console.WriteLine(DynamicOps["subtract"](3, 2));//1
Console.WriteLine(DynamicOps["inverse"](3));//-3
Console.WriteLine(ReflectionOps["abs"].Invoke(null, new object[] { -1 }));//1
Console.ReadLine();
}
}
}
one more example that you shouldn't use
delegate object CustomFunc(params object[] paramaters);
private static Dictionary<string, CustomFunc> CustomParamsOps = new Dictionary<string, CustomFunc>
{
{"add", parameters => (int) parameters[0] + (int) parameters[1]},
{"subtract", parameters => (int) parameters[0] - (int) parameters[1]},
{"inverse", parameters => -((int) parameters[0])}
};
Console.WriteLine(CustomParamsOps["add"](3, 2)); //5
Console.WriteLine(CustomParamsOps["subtract"](3, 2)); //1
Console.WriteLine(CustomParamsOps["inverse"](3)); //-3
I will provide a really short and simplified answer compared to the others. Everything in C# (classes, variables, properties, structs, etc) has a backed with tons of things your programs can hook into. This network of backend stuff slightly lowers the speed of C# when compared to "deeper" languages like C++, but also gives programmers a lot more tools to work with and makes the language easier to use. In this backend is included things like "garbage collection," which is a feature that automatically deletes objects from memory when there are no variables left that reference them. Speaking of reference, the whole system of passing objects by reference, which is default in C#, is also managed in the backend. In C#, Delegates are possible because of features in this backend that allow for something called "reflection."
From Wikipedia:
Reflection is the ability of a computer program to examine,
introspect, and modify its own structure and behavior at runtime.
So when C# compiles and it finds a Delegate, it is just going to make a function, and then store a reflective reference to that function in the variable, allowing you to pass it around and do all sorts of cool stuff with it. You aren't actually storing the function itself in the variable though, you are storing a reference, which is kinda like an address that points you to where the function is stored in RAM.

Passing anonymous/lambda functions to void delegates with no parameters? [C#]

I've been exploring C# delegates and anonymous/lambda functions, and I have some questions about how they interact. From what I understand, a simple delegate object can have predefined return and parameter types, and any named function with those same return/parameter types can be assigned to the delegate.
In my case, however, I've been working on a game where the Player can enqueue multiple Commands into their commandList. At some point after being added to the command list, commands are eventually executed by the player..
I started implementing this by creating specific subclasses for each command (AttackCommand, HealCommand, etc.), but then later found that to be tedious when it came to prototyping a variety of new commands. I thought it would be cool, for testing purposes, to create a CustomCommand class with a member delegate so that I could define and pass functions anonymously and quickly iterate on new game design ideas.
public class CustomCommand : Command {
public delegate void CommandDelegate();
private CommandDelegate func;
public CustomCommand( CommandDelegate del ){
func = del;
}
public Execute(){
func();
}
}
Then Player has a method that defines an anonymous function and uses it to construct a CustomCommand. However, something that confuses me a little bit is the fact that the arguments of this method seem to be able to be stored in the CustomCommand's delegate:
//inside Player class..
//command to steal gold from a target!
public CreateCustomCommand( Player targetPlayer ){
CustomCommand.CommandDelegate anonCommand = delegate()
{
//Steals up to amount passed..
int goldToSteal = targetPlayer.StealGold(25);
gold += goldToSteal;
};
CustomCommand newCommand = new CustomCommand( anonCommand );
commandList.Enqueue( newCommand );
}
//Command is automatically executed later..
I've tried this code, and not only does it compile, but it also works; money is stolen from the target and added to the source player. I'm happy that it works, but it's a little bit unsettling that I'm not sure what exactly is going on behind the scenes..
Here's what I'm having a hard time understanding:
Inside the CreateCustomCommand method (of Player), gold is in scope as it is a member of the Player class, and targetPlayer is in scope because it's a parameter.. But how is it that these things can be wrapped up in a anonymous function and passed to a void, parameterless delegate that's inside another object and still work? What's happening here? Does the creation of an anonymous function store references to all of the objects that it contains?
This seems extremely flexible compared to assigning named functions to delegates with matching return/parameter types, but are there any major drawbacks or pitfalls? Also, is this technique related to (or part of) any particular design pattern or programming methodology?
If I understand this correctly, this works because anonymous functions make use of closures. Closures are blocks of code that can capture (See: Variable Scope In Lambda Expressions) the variable environments in which they were made.
So, because the CreateCustomCommand method defined an anonymous function (a closure), the anonymous function captured and maintained access to the variables that were in scope of CreateCustomCommand.
Thanks to #HansPassant for pointing me in the right direction!

C# Benefit of Delegates [duplicate]

Can someone please break down what a delegate is into a simple, short and terse explanation that encompasses both the purpose and general benefits? I've tried to wrap my head around this and it's just not sinking in.
I have a function:
public long GiveMeTwoTimesTwo()
{
return 2 * 2;
}
This function sucks. What if I want 3 * 3?
public long GiveMeThreeTimesThree()
{
return 3 * 3;
}
Too much typing. I'm lazy!
public long SquareOf(int n)
{
return n * n;
}
My SquareOf function doesn't care what n is. It will operate properly for any n passed in. It doesn't know exactly what number n is, but it does know that n is an integer. You can't pass "Haha not an integer" into SquareOf.
Here's another function:
public void DoSomethingRad()
{
int x = 4;
long y = SquareOf(x);
Console.WriteLine(y);
}
Contrary to its name, DoSomethingRad doesn't actually do anything rad. However, it does write the SquareOf(4) which is 16. Can we change it to be less boring?
public void DoSomethingRad(int numberToSquare)
{
long y = SquareOf(numberToSquare);
Console.WriteLine(y);
}
DoSomethingRad is clearly still pretty fail. But at least now we can pass in a number to square, so it won't write 16 every time. (It'll write 1, or 4, or 9, or 16, or... zzzz still kinda boring).
It'd be nice if there was a way to change what happens to the number passed in. Maybe we don't want to square it; maybe we want to cube it, or subtract it from 69 (number chosen at random from my head).
On further inspection, it seems as though the only part of SquareOf that DoSomethingRad cares about is that we can give it an integer (numberToSquare) and that it gives us a long (because we put its return value in y and y is a long).
public long CubeOf(int n)
{
return n * n * n;
}
public void DoSomethingLeet(int numberToSquare)
{
long y = CubeOf(numberToSquare);
Console.WriteLine(y);
}
See how similar DoSomethingLeet is to DoSomethingRad? If only there was a way to pass in behavior (DoX()) instead of just data (int n)...
So now if we want to write a square of a number, we can DoSomethingRad and if we want to write the cube of a number, we can DoSomethingLeet. So if we want to write the number subtracted from 69, do we have to make another method, DoSomethingCool? No, because that takes too damn much typing (and more importantly, it hinders our ability to alter interesting behavior by changing only one aspect of our program).
So we arrive at:
public long Radlicious(int doSomethingToMe, Func<int, long> doSomething)
{
long y = doSomething(doSomethingToMe);
Console.WriteLine(y);
}
We can call this method by writing this:
Radlicious(77, SquareOf);
Func<int, long> is a special kind of delegate. It stores behavior that accepts integers and spits out longs. We're not sure what the method it points to is going to do with any given integer we pass; all we know is that, whatever happens, we are going to get a long back.
We don't have to give any parameters to SquareOf because Func<int, long> describes behavior, not data. Calling Radlicious(77, SquareOf) just gives Radlicious the general behavior of SquareOf ("I take a number and return its square"), not what SquareOf will do to any specific integer.
Now if you have understood what I am saying, then you have already one-upped me, for I myself don't really get this stuff.
* END ANSWER, BEGIN WANDERING IDIOCY *
I mean, it seems like ints could be perceived as just really boring behavior:
static int Nine()
{
return 9;
}
That said, the line between what is data and behavior appears to blur, with what is normally perceived as data is simply boring-ass behavior.
Of course, one could imagine super "interesting" behavior, that takes all sorts of abstract parameters, but requires a ton of information to be able to call it. What if it required us to provide the source code that it would compile and run for us?
Well, then our abstraction seems to have gotten us all the way back to square one. We have behavior so abstract it requires the entire source code of our program to determine what it's going to do. This is fully indeterminate behavior: the function can do anything, but it has to be provided with everything to determine what it does. On the other hand, fully determinate behavior, such as Nine(), doesn't need any additional information, but can't do anything other than return 9.
So what? I don't know.
In the simplest possible terms, it's essentially a pointer to a method.
You can have a variable that holds a delegate type (just like you would have an int variable that can hold an int type). You can execute the method that the delegate points to by simply calling your variable like a function.
This allows you to have variable functions just like you might have variable data. Your object can accept delegates from other objects and call them, without having to define all the possible functions itself.
This comes in very handy when you want an object to do things based on user specified criteria. For example, filtering a list based on a user-defined true/false expression. You can let the user specify the delegate function to use as a filter to evaluate each list item against.
A delegate is a pointer to a method. You can then use your delegate as a parameter of other methods.
here is a link to a simple tutorial.
The question I had was 'So, why would I want to do that?' You won't really 'get it' until you solve a programming problem with them.
It's interesting that no-one has mentioned one of key benefits of delegation - it's preferable to sub-classing when you realise that inheritance is not a magic bullet and usually creates more problems than it solves. It is the basis of many design patterns, most notably the strategy pattern.
A delegate instance is a reference to a method. The reason they are useful is that you can create a delegate that is tied to a particular method on a particular instance of a type. The delegate instance allows you to invoke that method on that particular instance even if the object on which you will invoke the method has left your lexical scope.
The most common use for delegate instances like this is to support the concept of callbacks at the language level.
It simply references a method. They come in great use with working with cross threading.
Here is an example right out of my code.
//Start our advertisiment thread
rotator = new Thread(initRotate);
rotator.Priority = ThreadPriority.Lowest;
rotator.Start();
#region Ad Rotation
private delegate void ad();
private void initRotate()
{
ad ad = new ad(adHelper);
while (true)
{
this.Invoke(ad);
Thread.Sleep(30000);
}
}
private void adHelper()
{
List<string> tmp = Lobby.AdRotator.RotateAd();
picBanner.ImageLocation = #tmp[0].ToString();
picBanner.Tag = tmp[1].ToString();
}
#endregion
If you didnt use a delegate you wouldn't be able to crossthread and call the Lobby.AdRotator function.
Like others have said, a delegate is a reference to a function. One of the more beneficial uses(IMO) is events. When you register an event you register a function for the event to invoke, and delegates are perfect for this task.
In the most basic terms, a delegate is just a variable that contains (a reference to) a function. Delegates are useful because they allow you to pass a function around as a variable without any concern for "where" the function actually came from.
It's important to note, of course, that the function isn't being copied when it's being bundled up in a variable; it's just being bound by reference. For example:
class Foo
{
public string Bar
{
get;
set;
}
public void Baz()
{
Console.WriteLine(Bar);
}
}
Foo foo = new Foo();
Action someDelegate = foo.Baz;
// Produces "Hello, world".
foo.Bar = "Hello, world";
someDelegate();
In most simplest terms, the responsibility to execute a method is delegated to another object. Say the president of some nation dies and the president of USA is supposed to be present for the funeral with condolences message. If the president of USA is not able to go, he will delegate this responsibility to someone either the vice-president or the secretary of the state.
Same goes in code. A delegate is a type, it is an object which is capable of executing the method.
eg.
Class Person
{
public string GetPersonName(Person person)
{
return person.FirstName + person.LastName;
}
//Calling the method without the use of delegate
public void PrintName()
{
Console.WriteLine(GetPersonName(this));
}
//using delegate
//Declare delegate which matches the methods signature
public delegate string personNameDelegate(Person person);
public void PrintNameUsingDelegate()
{
//instantiate
personNameDelegate = new personNameDelegate(GetPersonName);
//invoke
personNameDelegate(this);
}
}
The GetPersonName method is called using the delegate object personNameDelegate.
Alternatively we can have the PrintNameUsingDelegate method to take a delegate as a parameter.
public void PrintNameUsingDelegate(personNameDelegate pnd, Person person)
{
pnd(person);
}
The advantage is if someone want to print the name as lastname_firstname, s/he just has to wrap that method in personNameDelegate and pass to this function. No further code change is required.
Delegates are specifically important in
Events
Asynchronous calls
LINQ (as lambda expressions)
If you were going to delegate a task to someone, the delegate would be the person who receives the work.
In programming, it's a reference to the block of code which actually knows how to do something. Often this is a pointer to the function or method which will handle some item.
In the absolute most simplest terms I can come up with is this: A delegate will force the burdens of work into the hands of a class that pretty much knows what to do. Think of it as a kid that doesn't want to grow up to be like his big brother completely but still needs his guidance and orders. Instead of inheriting all the methods from his brother (ie subclassing), he just makes his brother do the work or The little brother does something that requires actions to be taken by the big brother. When you fall into the lines of Protocols, the big brother defines what is absolutely required, or he might give you flexibility to choose what you want to make him do in certain events (ie informal and formal protocols as outlined in Objective-C).
The absolute benefit of this concept is that you do not need to create a subclass. If you want something to fall in line, follow orders when an event happens, the delegate allows a developed class to hold it's hand and give orders if necessary.

Method writing pattern

I recently noticed the following code which basically defines a class method
public Func<string, string> SampleMethod = inputParam =>
{
return inputParam.ToUpper();
};
which is the same as doing it in the old fashioned way
public string SampleMethod(string inputParam )
{
return inputParam.ToUpper();
}
My question - why would I prefer the first over the second? My eyes are maybe more trained to understand the second style quicker. I find it similar to the difference between SMS lingo and plain old english.
Those two things are fundamentally different. The former is a field of a delegate type while the latter is really a method. The tiniest difference I can think of is that you can modify the first one dynamically at runtime and assign another method reference to it while the second is fixed.
You shouldn't normally prefer the first over the second if your purpose is to write a simple method for a class in C#.
An example that makes the first extremely fragile:
var c = new SomeClass();
c.SampleMethod = inputParam => inputParam.ToLower();
c.DoSomeTaskThatReliesOnSampleMethodReturningAnUpperCaseString();
c.SampleMethod = null;
c.DoSomeTaskThatCallsSampleMethod(); // NullReferenceException
This style of programming is common in language like Javascript where an object is fundamentally a dynamic creature built upon a simple dictionary.
They are actually not the same at all. The second is a regular member method, that returns ToUpper on the input string.
The first, on the other hand, is a Func member variable, that happens to point to a delegate, that implements the same functionality. However, as this is a method pointer, you can substitute the delegate with any other delegate of the same type at runtime. I.e. you can completely redefine what it means to call this method.
One benefit of the second way is it's better from a unit testing perspective - you can test your class and know that the method will correctly return the uppercase string. With the first method, you can change the method at runtime, so unit testing is much harder.

Using Closures to keep track of a variable: Good idea or dirty trick?

Ok, i have a need to be able to keep track of value type objects which are properties on another object, which cannot be done without having those properties implement an IObservable interface or similar. Then i thought of closures and the famous example from Jon Skeet and how that prints out 9 (or 10) a bunch of times and not an ascending order of numbers. So i thought why not do this:
Class MyClass
{
...
Func<MyValueType> variable;
...
public void DoSomethingThatGetsCalledOften()
{
MyValueType blah = variable(); //error checking too not shown for brevity
//use it
}
...
}
... in some other consuming code ...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
//then myClass will get the current value of the variable whenever it needs it
Obviously this would require some understanding of how closures work, but my question is this: is this a good idea or a dirty hack and a misuse of the closure system?
Edit: Since some people seem to be misunderstanding what i'm trying to say, here's a console program which demonstrates it:
using System;
using System.Linq;
namespace Test
{
class Program
{
public static void Main()
{
float myFloat = 5;
Func<float> test = () => myFloat;
Console.WriteLine(test());
myFloat = 10;
Console.WriteLine(test());
Console.Read();
}
}
}
That will print out 5 then 10.
You have stumbled upon the famous koan: Closures are a poor man's object. You are using Action<T> to substitute for a property getter of type T. Such a thing would be (slightly) less of a dirty trick in a more dynamic language, since it could be implemented by injecting a getter that’s decorated with your logging function, but in C# there isn’t an elegant way to monkeypatch someone’s property when they’re not expecting it.
As a mechanism for obtaining the value fro a property, it'll work (but it won't provide any mechanism for noticing updates promptly). However, it depends on how you intend to use it. To do this conveniently you'll need to use a pile of lambdas in the code, or have some DynamicMethod / Expression code do it at runtime. In most cases, something more similar to reflection would be more convenient.
I wouldn't necessarily worry about the "value type" aspect; in most cases this isn't a bottleneck, despite the FUD - and it is generally a lot easier to handle such code with object than it is via generics or similar.
I have some code in my IDE that demonstrates DynamicMethod vs raw reflection (that I intend to blog some day soon), showing how reflection-based code doesn't have to be slow (or just use HyperDescriptor).
The other option is to implement the correct interfaces / add the correct events. Perhaps via PostSharp, perhaps via dynamic types (inheriting and overriding at runtime), perhaps with regular code.
You would need to type your variable member as Func<MyValueType> (or another delegate that returns MyValueType), but you wouldn't be able to assign the value of blah in that manner. Just as with using the closure in the foreach loop above, it's only going to evaluate at a point in time. This isn't a way to keep your variable's value in sync with the other object. There is, in fact, no way to do that without either:
continuously monitoring the value of the other instance's property in some sort of loop, like a Timer
implementing a change notification event on the other instance's class
You would be able to implement a property like that (since a property is evaluated at every call), but then what's the sense in using a custom delegate, other than the fact that you don't have to know anything about the other instance.
Edit
I'll try to make this a little clearer. Using this code that you posted:
Class MyClass
{
...
Action<MyValueType> variable;
...
MyValueType blah = variable();
//use it
...
}
...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
First, for this to be functional, variable should be Func<MyValueType>, not Action<MyValueType> (Func returns a value, Action does not; since you're trying to assign a value to a variable, you need the expression to return a value).
Second, the main issue with your approach is--assuming I'm reading your code correctly--you're attempting to assign the value of the instance variable blah to the evaluated value of variable() within the class declaration. This won't work for a couple of reasons:
assignments within class declarations cannot access instance members (which variable is)
the assignment of a variable within a class declaration just occurs upon construction of the object. Even if the first condition were present, you would simply get a NullReferenceException upon instantiating your object, since it would be trying to evaluate variable, which would be null at that time
even disregarding the first two, the value of blah would still only represent the evaluated value of variable() at whatever time it was evaluated. It would not "point to" that function and be automatically kept in sync, as it seems like you're trying to do.
If you aren't looking for some sort of automatic synchronization, then there's nothing stopping you from just keeping the Func<MyValueType> delegate around to evaluate; there's nothing particularly good or bad about that approach, and it isn't a closure unless the delegate (in your case a lambda expression) involves the use of a local variable.

Categories