Are C# anonymous lambdas evaluated every time they are used? - c#

Following How to decorate code in C# wiithout C/C++ - like macros I have just switched my logging system over to accept log messages as lambdas rather than as strings:
void Log(Func<string> msg)
{
if (logIsEnabled)
{
Debug.Write(msg());
}
}
My understanding is that this is much better, performance-wise, in that if I write:
Log(() => "foo(" + myInteger + ")");
then the string foo(42) is constructed only if logIsEnabled. For the sake of this question, let's assume that Log() is being called at high frequency, and constructing these strings for the log comes at an undesirable cost.
Suddenly I worried, though - is a lambda being instantiated every time this line of code is reached? Might that be more of a performance cost than constructing a string? I'm not clear on what's happening here, under the hood.
So, my question is: how is the lambda actually implemented? Is it constructed at compile-time and passed just as a pointer to a function? Is it constructed on first use and on subsequent passes just a pointer? Or is it constructed every time the line of code executes?

is a lambda being instantiated every time this line of code is reached?
Yes. Not only a new Func<string> is instantiated every time, but also a small compiler-generated class. Let's post some code to SharpLab, and see what comes out:
using System;
class Program
{
static bool logIsEnabled;
static void Main()
{
logIsEnabled = true;
int myInteger = 13;
Log(() => "foo(" + myInteger + ")");
}
static void Log(Func<string> msg)
{
if (logIsEnabled)
{
Console.WriteLine(msg());
}
}
}
SharpLab output (sanitized):
using System;
using System.Runtime.CompilerServices;
internal class Program
{
[CompilerGenerated]
private sealed class DisplayClass
{
public int myInteger;
internal string M()
{
return string.Concat("foo(", myInteger.ToString(), ")");
}
}
private static bool logIsEnabled;
private static void Main()
{
DisplayClass displayClass = new DisplayClass();
logIsEnabled = true;
displayClass.myInteger = 13;
Log(new Func<string>(displayClass.M));
}
private static void Log(Func<string> msg)
{
if (logIsEnabled)
{
Console.WriteLine(msg());
}
}
}
The DisplayClass is the closure that the compiler had to generate, in order to hold the myInteger variable. This variable is hoisted to a public field of the DisplayClass class.
The Visual Studio can help you at detecting that a variable has been captured. Just hover the mouse over the lambda operator (=>).
It is possible to avoid the allocation of the two objects by passing the myInteger as an argument, instead of relying on the convenience of captured variables and closures. Here is how:
using System;
class Program
{
static bool logIsEnabled;
static void Main()
{
logIsEnabled = true;
int myInteger = 13;
Log(arg => "foo(" + arg + ")", myInteger);
}
static void Log<TArg>(Func<TArg, string> msg, TArg arg)
{
if (logIsEnabled)
{
Console.WriteLine(msg(arg));
}
}
}
SharpLab output (sanitized):
using System;
using System.Runtime.CompilerServices;
internal class Program
{
[Serializable]
[CompilerGenerated]
private sealed class C
{
public static readonly C singleton = new C();
public static Func<int, string> lambda;
internal string M(int arg)
{
return string.Concat("foo(", arg.ToString(), ")");
}
}
private static bool logIsEnabled;
private static void Main()
{
logIsEnabled = true;
int arg = 13;
Log(C.lambda ?? (C.lambda = new Func<int, string>(C.singleton.M)), arg);
}
private static void Log<TArg>(Func<TArg, string> msg, TArg arg)
{
if (logIsEnabled)
{
Console.WriteLine(msg(arg));
}
}
}
Now the compiler generated a singleton (the C class), and the Func<TArg, string> is instantiated only once per TArg type. So if your program uses the Log<TArg> with ints, strings and decimals, only a Func<int, string>, a Func<string, string> and a Func<decimal, string> will be created in total, irrespective of how many times the Log<TArg> will be invoked.
In case you want to pass more than one arguments to the Log method, you'll have to write additional Log<TArg1, TArg2>, Log<TArg1, TArg2, TArg3> etc overloads.

Related

Defining & using array of delegates

Wow, this would be so simple in C or C++. I'm trying to write a tool in C# to parse compiled C code (i.e. the assembler output) in order to calculate the stack usage of every function in an embedded system application. But that's not what's important here. How can I create an array of "function pointers" and iterate through them, calling the functions to which they point?
I have tried about 1000 variations of delegate and Delegate and Func and parameterized constructors and can't figure out how to get rid of all of the nasty red squiggly lines in my VS2013 editor:
public struct Parser
{
public string platformName;
public Delegate d_isThisPlatform;
public Delegate d_parseAsm;
public Parser(string platformName, Delegate isThisPlatform, Delegate parseAsm)
{
this.platformName = platformName;
this.d_isThisPlatform = isThisPlatform;
this.d_parseAsm = parseAsm;
}
};
public static bool PIC32MX_GCC_isThisPlatform(string asmFileContents)
{
return false; // stub
}
public static bool PIC32MX_GCC_parseAsm(string asmFileContents)
{
return false; // stub
}
public static bool M16C_IAR_isThisPlatform(string asmFileContents)
{
return true; // stub
}
public static bool M16C_IAR_parseAsm(string asmFileContents)
{
return false; // stub
}
const Parser[] parsers =
{
new Parser("PIC32MX_GCC", PIC32MX_GCC_isThisPlatform, PIC32MX_GCC_parseAsm),
new Parser("M16C_IAR", M16C_IAR_isThisPlatform, M16C_IAR_parseAsm)
};
public Parser findTheRightParser(string asmFileContents)
{
foreach(Parser parser in parsers)
{
if (parser.d_isThisPlatform(asmFileContents))
{
Console.WriteLine("Using parser: ", parser.platformName);
return parser;
}
}
}
My current error (for the code as listed above) is "The best overloaded method match for 'staticAnalysis.Program.Parser.Parser(string,System.Delegate,System.Delegate)' has some invalid arguments." I am not sold on using System.Delegate; if I could simply use delegate that would be my preference, but more important than that, I'm interested in something simple.
Delegate is too broad a class for what you're trying to do. You need to specify what input(s) the delegate can expect and what output (if any) it will generate. You can either specify them as functions that take a string and return a bool:
public struct Parser
{
public string platformName;
public Func<string, bool> d_isThisPlatform;
public Func<string, bool> d_parseAsm;
public Parser(string platformName,Func<string, bool> isThisPlatform, Func<string, bool> parseAsm)
{
this.platformName = platformName;
this.d_isThisPlatform = isThisPlatform;
this.d_parseAsm = parseAsm;
}
};
or define a specific delegate type and declare your fields and parameters as that type:
public struct Parser
{
public delegate bool ParseDelegate(string content);
public string platformName;
public ParseDelegate d_isThisPlatform;
public ParseDelegate d_parseAsm;
public Parser(string platformName,ParseDelegate isThisPlatform, ParseDelegate parseAsm)
{
this.platformName = platformName;
this.d_isThisPlatform = isThisPlatform;
this.d_parseAsm = parseAsm;
}
};
After you fix that, you're going to end up with two other compiler errors. The fix for those is left for your learning experience...

how to declare a void in constructor c#?

I found this code (no conpiler error, it's mean code no error) that is "PingCompletedEventHandler" has constructor like PingCompletedEventHandler(abc) with static void abc(object s, PingCompletedEventArgs e){} right?
static PingCompletedEventHandler Ping_completed(object s, PingCompletedEventArgs e)
{
// This code work fine, it used method void abc below
PingCompletedEventHandler a = new PingCompletedEventHandler(abc);
value.Add("abc");
lock (#lock)
{
instances -= 1;
}
if (e.Reply.Status == IPStatus.Success)
{
string abcd = string.Concat("Active IP: ", e.Reply.Address.ToString());
value.Add("abc");
value.Add(abcd);
result += 1;
}
return a;
}
static void abc(object s, PingCompletedEventArgs e)
{
}
How can they do this. I have tested in my code, it doesn't work. Here is my test:
class Class1
{
static void abcd(int a){
}
public
// Error here: Class1.abcd(int)' is a 'method' but is used like a 'type'
Class1(abcd)
{
}
}
class Class3
{
public static void Main()
{
Class1 asd = new Class1();
}
}
When creating event-handlers you provide a pointer to method within the handlers constructor. This is not "a void", it is a delegate pointing to a method of type void.
The constructor therefor should look similar to:
delegate void HandlerMethod(objects s, PingCompletedEventArgs e);
class PingCompletedEventHandler {
PingCompletedEventHandler(HandlerMethod handler) { ... }
}
Now you can call this constructor with new PingCompletedEventHandler(abc) as abc is a method of type void expecting a param of type objectand of of type PingCompletedEventArgs.
Further reading on delegates here on MSDN
EDIT: Since .NET 3.0 there is also the easier to read Action-type that can be used for methods that do not return anything (void). Thus you may also use PingCompletedEventHandler(Action<object, PingCompletedEventArgs> handler) instead of defining your own delegate.
Further EDIT: To get this to work for your test, your constructor for Class1 should look like this: Class1(Action<int> theAction).
When you want a Function as a Parameter of a Method or a Constructor then you have to use a Delegate
The easiest way is using a Action<...> if you have a Void return type or a Func<T, ...> if you have something else as return type.
In your case it will look like this:
public ClassConstructor(Action<YourParameter> myDelegate)
{
}
For Example:
This is a very simple function and you want to create a delegate of this:
private static int Add(int a, int b)
{
return a + b;
}
then you need a delegate that accepts an int as return type and two ints as parameters.
So you define a Func<...> like this and assign the original method:
Func<int, int, int> addDelegate = Add;
the usage is like using Add only with an other name:
var result = addDelegate(2, 5);

Efficient way to call a method dynamically based on its name without reflection

Let me try to simplify my question:
I have four classes: Admins, Users, Players, Roles
The database returns names of methods that I will need to execute. For example if Admins_GetName is returned then GetName() method will need to be executed on the Admins class.
If Players_GetRank is returned then GetRank() method will need to be called on the Players class.
I don't want to write a huge IF or SWITCH statement with all my business logic in it. What would be the most efficient solution WITHOUT using reflection ? If possibly I would like to avoid the performance hit that reflection brings.
Keep in mind that all methods may have different parameters and but will return strings.
Here is what I'm thinking to do now:
1) Have a method with a switch statement that will break apart the database value and find the class and method I need to execute.
Something like:
switch(DbValue)
{
case DbValue == "Admins_GetName":
Declare a delegate to Admins.GetName();
return;
case: DbValue = "Players_GetRank"
Declare a delegate to Players.GetRank();
return;
.
.
.
etc
}
return class/method reference;
2) Pass the declaration from above to:
var myValue = Retrieved method.invoke()
Can you guys suggest me with the best way to accomplish this or help me out with the correct syntax on my idea of how to implement it.
Thank you.
Needs a little more context; for example, do all the methods in question have the same signature? In the general case, reflection is the most appropriate tool for this, and as long as you aren't calling it in a tight loop, it will be fine.
Otherwise, the switch statement approach is reasonable, but has the maintenance overhead. If that is problematic, I would be tempted to build a delegate cache at runtime, for example:
using System;
using System.Collections.Generic;
public class Program
{
public string Bar { get; set; }
static void Main()
{
var foo = new Foo();
FooUtils.Execute(foo, "B");
FooUtils.Execute(foo, "D");
}
}
static class FooUtils
{
public static void Execute(Foo foo, string methodName)
{
methodCache[methodName](foo);
}
static readonly Dictionary<string, Action<Foo>> methodCache;
static FooUtils()
{
methodCache = new Dictionary<string, Action<Foo>>();
foreach (var method in typeof(Foo).GetMethods())
{
if (!method.IsStatic && method.ReturnType == typeof(void)
&& method.GetParameters().Length == 0)
{
methodCache.Add(method.Name, (Action<Foo>)
Delegate.CreateDelegate(typeof(Action<Foo>), method));
}
}
}
}
public class Foo
{
public void A() { Console.WriteLine("A"); }
public void B() { Console.WriteLine("B"); }
public void C() { Console.WriteLine("C"); }
public void D() { Console.WriteLine("D"); }
public string Ignored(int a) { return ""; }
}
That approach can be extended to multiple target types by using generics:
static class FooUtils
{
public static void Execute<T>(T target, string methodName)
{
MethodCache<T>.Execute(target, methodName);
}
static class MethodCache<T>
{
public static void Execute(T target, string methodName)
{
methodCache[methodName](target);
}
static readonly Dictionary<string, Action<T>> methodCache;
static MethodCache()
{
methodCache = new Dictionary<string, Action<T>>();
foreach (var method in typeof(T).GetMethods())
{
if (!method.IsStatic && method.ReturnType == typeof(void)
&& method.GetParameters().Length == 0)
{
methodCache.Add(method.Name, (Action<T>)
Delegate.CreateDelegate(typeof(Action<T>), method));
}
}
}
}
}

Initialization of static fields in C# generic types

I understood from this answer that C# static field initializers "are executed... prior to the first use of a static field of that class," but that still produces results I didn't expect, at least with generic types.
Coming from the Java world, I was missing my rich enums, and I thought with C#'s more serious generics that I ought to be able to replicate them with a minimum of boilerplate. Here (stripped of some details, like comparability) is what I came up with:
public class AbstractEnum<T> where T : AbstractEnum<T>
{
static readonly IDictionary<String, T> nameRegistry = new Dictionary<String, T>();
readonly String name;
protected AbstractEnum (String name)
{
this.name = name;
nameRegistry[name] = (T) this;
}
public String Name {
get {
return name;
}
}
public static T ValueOf(String name) {
return nameRegistry[name];
}
public static IEnumerable<T> Values {
get {
return nameRegistry.Values;
}
}
}
And some example subclasses:
public class SomeEnum : AbstractEnum<SomeEnum> {
public static readonly SomeEnum V1 = new SomeEnum("V1");
public static readonly SomeEnum V2 = new SomeEnum("V2");
SomeEnum(String name) : base(name) {
}
}
public class OtherEnum : AbstractEnum<OtherEnum> {
public static readonly OtherEnum V1 = new OtherEnum("V1");
public static readonly OtherEnum V2 = new OtherEnum("V2");
OtherEnum(String name) : base(name) {
}
}
This looks good and more or less does the trick... except that, following the letter of the spec, the actual instances (SomeEnum.V1, OtherEnum.V1 etc.) don't get initialized unless at least one of them is referred to explicitly. Static fields/methods in the base class don't count. So, for instance, the following:
Console.WriteLine("Count: {0}", SomeEnum.Values.Count());
foreach (SomeEnum e in SomeEnum.Values) {
Console.WriteLine(e.Name);
}
writes Count: 0, but if I add the following line --
Console.WriteLine("SomeEnum.V1: " + SomeEnum.V1.Name);
-- even after the above, I get:
Count: 2
V1
V2
(Note, by the way, that initializing the instances in a static constructor makes no difference.)
Now, I can fix this by marking nameRegistry as protected and pushing Values and ValueOf down into the subclasses, but I was hoping to keep all the complexity in the superclass and keep the boilerplate to a minimum. Can anyone whose C#-fu is superior to mine come up with a trick for making the subclass instances "self-executing"?
Note: FWIW, this is in Mono, on Mac OS. YM in MS .NET, on Windows, MV.
ETA: For monoglot C# developers (or even polyglot developers whose experience is limited to languages starting with 'C') wondering WTF I'm trying to do: this. C# enums take care of the type safety issue, but they're still missing everything else.
I came up with this - not entirely pleasing, but does do the job:
public static IEnumerable<T> Values
{
get
{
if (nameRegistry.Count > 0)
{
return nameRegistry.Values;
}
var aField = typeof (T).GetFields(
BindingFlags.Public | BindingFlags.Static)
.FirstOrDefault();
if (aField != null)
aField.GetValue(null);
return nameRegistry.Values;
}
}
EDIT Here's a slightly different version that should address VinayC's concerns in the comments. The problem was this: thread A calls Values(). While the static constructor of SomeEnum is running, after it's added V1 but before it adds V2, thread B calls values. In the code as originally written, it would be handed an IEnumerable that might only yield V1. So you could get incorrect results from Values() if a second thread calls during the very first call to Values() for any particular type.
The version below uses a boolean flag rather than relying on a non-zero count in nameRegistry. In this version it is still possible that the reflection code to run more than once, but no longer possible to get wrong answers from Values(), since by the time the reflection code completes, the nameRegistry is guaranteed to be fully initialized.
private static bool _initialized;
public static IEnumerable<T> Values
{
get
{
if (_initialized)
{
return nameRegistry.Values;
}
var aField = typeof(T).GetFields(
BindingFlags.Public | BindingFlags.Static)
.FirstOrDefault();
if (aField != null)
aField.GetValue(null);
_initialized = true;
return nameRegistry.Values;
}
}
Admittedly, I don't know what RichEnums are, but does this C# not do what you want?
public enum SomeEnum
{
V1,
V2
}
class Program
{
static void Main(string[] args)
{
var values = Enum.GetValues(typeof (SomeEnum));
Console.WriteLine("Count: {0}", values.Length);
foreach (SomeEnum e in values)
{
Console.WriteLine(e);
}
}
}
How about:
public class BaseRichEnum
{
public static InitializeAll()
{
foreach (Type t in Assembly.GetExecutingAssembly().GetTypes())
{
if (t.IsClass && !t.IsAbstract && typeof (BaseRichEnum).IsAssignableFrom(t))
{
t.GetMethod("Initialize").Invoke(null, null); //might want to use flags on GetMethod
}
}
}
}
public class AbstractEnum<T> : BaseRichEnum where T : AbstractEnum<T>
{
static readonly IDictionary<String, T> nameRegistry = new Dictionary<String, T>();
readonly String name;
protected AbstractEnum (String name)
{
this.name = name;
nameRegistry[name] = (T) this;
}
public String Name {
get {
return name;
}
}
public static T ValueOf(String name) {
return nameRegistry[name];
}
public static IEnumerable<T> Values {
get {
return nameRegistry.Values;
}
}
}
And then:
public class SomeEnum : AbstractEnum<SomeEnum>
{
public static readonly SomeEnum V1;
public static readonly SomeEnum V2;
public static void Initialize()
{
V1 = new SomeEnum("V1");
V2 = new SomeEnum("V2");
}
SomeEnum(String name) : base(name) {
}
}
Then you have to call BaseRichEnum.InitializeAll() in application startup code. I think it's better to impose this simple requirement on clients, thereby making visible the mechanism, than to expect future maintainers to grasp the subtleties of static-time initialization.
I don't like below solution as such but...
public class AbstractEnum<T> where T : AbstractEnum<T>
{
...
private static IEnumerable<T> ValuesInternal {
get {
return nameRegistry.Values;
}
}
public IEnumerable<T> Values {
get {
return ValuesInternal;
}
}
}
You have to use like SomeEnum.V1.Values - I know it sucks!
Yet another alternative that would involve some work is
public class AbstractEnum<T> where T : AbstractEnum<T>
{
...
protected static IEnumerable<T> ValuesInternal {
get {
return nameRegistry.Values;
}
}
}
public class SomeEnum : AbstractEnum<SomeEnum> {
...
public static IEnumerable<SomeEnum> Values
{
get
{
return ValuesInternal;
}
}
}
I would go with the second option.

Declare private static members in F#?

I decided to port the class in C# below to F# as an exercise.
It was difficult. I only notice three problems
1) Greet is visible
2) I can not get v to be a static class variable
3) I do not know how to set the greet member in the constructor.
How do i fix these? The code should be similar enough that i do not need to change any C# source. ATM only Test1.v = 21; does not work
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CsFsTest
{
class Program
{
static void Main(string[] args)
{
Test1.hi("stu");
new Test1().hi();
Test1.v = 21;
var a = new Test1("Stan");
a.hi();
a.a = 9;
Console.WriteLine("v = {0} {1} {2}", a.a, a.b, a.NotSTATIC());
}
}
class Test1
{
public int a;
public int b { get { return a * 2; } }
string greet = "User";
public static int v;
public Test1() {}
public Test1(string name) { greet = name; }
public static void hi(string greet) { Console.WriteLine("Hi {0}", greet); }
public void hi() { Console.WriteLine("Hi {0} #{1}", greet, v); }
public int NotSTATIC() { return v; }
}
}
F#
namespace CsFsTest
type Test1 =
(*
public int a;
public int b { get { return a * 2; } }
string greet = "User";
public static int v;
*)
[<DefaultValue>]
val mutable a : int
member x.b = x.a * 2
member x.greet = "User" (*!! Needs to be private *)
[<DefaultValue>]
val mutable v : int (*!! Needs to be static *)
(*
public Test1() {}
public Test1(string name) { greet = name; }
*)
new () = {}
new (name) = { }
(*
public static void hi(string greet) { Console.WriteLine("Hi {0}", greet); }
public void hi() { Console.WriteLine("Hi {0} #{1}", greet, v); }
public int NotSTATIC() { return v; }
*)
static member hi(greet) =
printfn "hi %s" greet
member x.hi() =
printfn "hi %s #%i" x.greet x.v
member x.NotSTATIC() =
x.v
The F# language has some constructs that don't have any equivalent in C#, but it has almost everything that you can use in C#. This means that if you simply translate code from C# to F#, you'll end up using only a subset of F#. As a result, it is sometimes better to look for some specific F# constructs.
I think this is also the case of static members. In addition to classes, you can also organize F# code using modules and modules provide a natural way for declaring static data and functions. Here is an example of module for greeting:
// modules are automatically 'static' (from the C# point of viedw)
module Greetings =
// public mutable field inside a module
let mutable how = "Hello "
// global function that uses the field
let greet name =
Console.WriteLine(how + name)
// modify the global field and invoke global function
Greetings.how <- "Ahoj "
Greetings.greet("Tomas")
If you need some static functionality and some instance functionality, it is usually easy to split the functionality between a module and a standard class. The obvious benefit is that it gives you easier syntax, but it may also help structuring the code:
type Person(name) =
member GreetMe() =
Greetings.greet(name)
Members inside module can be declared as private or internal if you want to keep them hidden from the user. For example if you wanted to make the how field accessible only to your assembly, you could write:
let mutable internal how = "Hello "
I think this gives you more idiomatic F# code, so I would probably prefer this style of programming when writing F# code. If you plan to use this from C#, then modules will appear as static classes, which are also easy to use.
As a side-note, it is generally recomended to avoid using too many mutable members. However, if you're using them for some kind of configuration then I suppose it is OK.
Below is some F# that compiles against the C# client.
In .NET, one very rarely exposes public fields; I would recommend against it. The F# syntax for exposing fields is somewhat cumbersome.
namespace CsFsTest
open System
type Test1 =
val mutable private greet : string
[<DefaultValue>]
val mutable public a : int
[<DefaultValue>]
static val mutable private vv : int
static member v with get() = Test1.vv
and set(x) = Test1.vv <- x
member this.b = this.a*2
static member hi(greet:string) = Console.WriteLine("Hi {0}", greet)
member this.hi() = Console.WriteLine("Hi {0} #{1}", this.greet, Test1.v)
new() = { greet = "User" }
new(name : string) = { greet = name }
member this.NotSTATIC() = Test1.v
You're defining greet as a property. It doesn't need to be one.
// these are the same
member x.greet = "User"
member x.greet with get() = "User"
It can just be a variable.
val mutable private greet : string
new () = { greet = "User" }
new (name) = { greet = name }
F# doesn't allow you to have public static class variables. You have to use a getter/setter.

Categories