Defining & using array of delegates - c#

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...

Related

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

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.

Static type-checking of dynamic types not sharing an interface in C#

Say I have some external classes that have methods sharing a signature by convention, but that do not implement an interface:
class A {
public string getError();
}
class B {
public string getError();
}
If I want to create a utility function that accepts objects of either type, I could use dynamic:
void printError(dynamic obj) {
Console.WriteLine("Error: {0}", obj.getError());
}
But if I passed a some class C without a getError method, this would be a runtime error. Given that I can't modify A or B (directly), is there a way to implement this so that it would be a compile-time error to pass a type without a getError method, similar to what we'd get with C++ templates?
It sounds like you have an XY Problem. Instead of figuring out how to make your code less type safe, why not just use a overloads and refactor?
public void PrintError(A obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
public void PrintError(B obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
The above code solves your problem, but its no longer DRY. This is where we refactor:
public void PrintError(A obj)
{
PrintError(obj.getError());
}
public void PrintError(B obj)
{
PrintError(obj.getError());
}
//This is private, so you can only call PrintError publicly with an A or B instance
private void PrintError(string error)
{
Console.WriteLine("Error: {0}", error);
//maybe some more logic
}
Now you have type safety, you aren't repeating yourself and you are not "fighting the language" by using it in a way counter to how it was designed.
Use more than one prototype
You can of course define more than one prototype, where each prototype accepts a different class. The compiler will automatically pick the method signature that matches. Example:
public static void PrintError(ExternalClasses.A a)
{
Console.WriteLine(a.getError());
}
public static void PrintError(ExternalClasses.B b)
{
Console.WriteLine(b.getError());
}
Use a single prototype, but with implicit conversion
Another approach would be to define your own class and set up implicit conversion:
public class ErrorContainer
{
protected string _error = null;
public string getError()
{
return _error;
}
public override string ToString()
{
return getError();
}
static public implicit operator ErrorContainer(ExternalClasses.A a)
{
var e = new ErrorContainer();
e._error = a.getError();
return e;
}
static public implicit operator ErrorContainer(ExternalClasses.B b)
{
var e = new ErrorContainer();
e._error = b.getError();
return e;
}
}
Then you can define PrintError to accept an ErrorContainer:
public static void PrintError(ErrorContainer e)
{
Console.WriteLine(e);
}
...which allows you to "pass" either type:
var a = new ExternalClasses.A();
PrintError(a);
var b = new ExternalClasses.B();
PrintError(b);
Under the covers, of course, both A and B are converted to an ErrorContainer.
Example on DotNetFiddle

Accessing extension methods via generics always matches the least specific option?

There is a set of classes that I do not own - I cannot change them.
I'd like to add an identifying parameter to each, using an existing field in each class that has one.
So, I created a set of extension methods to fetch this field from each class, with a default for any class that does not have a specific implementation.
This works just fine when accessing the new extension method directly (the first three writes in the example below), but when the instances are first passed into a generic method, then the extension method selected is always the one for object (the second three writes).
Am I doing something wrong, or is this a limitation of the C# compiler?
public class Call { public string Number { get; set; } }
public class Message { public string Address { get; set; } }
public class Unknown { }
public static class Extensions
{
public static string ID(this object item) { return "Unknown"; }
public static string ID(this Call item) { return item.Number; }
public static string ID(this Message item) { return item.Address; }
}
internal class Program
{
private static void Main()
{
var call = new Call { Number = "555-1212" };
var msg = new Message { Address = "you#email.com" };
var other = new Unknown();
// These work just as I would expect
// - printing out Number, Address, or the default
System.Console.WriteLine("Call = {0}", call.ID());
System.Console.WriteLine("Message = {0}", msg.ID());
System.Console.WriteLine("Unknown = {0}", other.ID());
System.Console.WriteLine();
// These all print out "Unknown"
System.Console.WriteLine("Call = {0}", GetID(call));
System.Console.WriteLine("Message = {0}", GetID(msg));
System.Console.WriteLine("Unknown = {0}", GetID(other));
}
public static string GetID<T>(T item)
{
return item.ID();
}
}
Overload resolution is performed at compile-time. The compiler knows nothing about T, so the only applicable overload is this one:
public static string ID(this object item) { return "Unknown"; }
If you want to effectively perform overload resolution at execution time, and if you're using C# 4, you might want to consider using dynamic - which unfortunately doesn't support extension methods directly:
public static string GetID(dynamic item)
{
return Extensions.ID(item);
}

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.

Returning a function pointer

I'm trying to create a url builder similar to the one in asp mvc except our methods are frequently changing parameters and breaking pages.
Does anyone know if it's possible to coerce c# into allowing event like syntax to be returned from a delegate like this:
new UrlBuilder2<FakeController>(x => { return x.ActionWithInt; });
The class would be similar to this:
public class UrlBuilder<TController>
{
public UrlBuilder2(Func<TController, TType> action)
{
}
}
Basically I want to know what Type to use for TType. Or if it's at all possible.
Edit -
I would (if possible) like to use just the method, similar to how you would assign an event ( clickEvent =+ myMethod;)
Not exactly sure what you want to achieve, but assuming you want to generate link simlar to this:
MyForm/MyMethod.aspx
based on WebForm (or any other class) like this:
public class MyForm {
public void MyMethod() {
// Something here
}
public void MethodWithParams(int i, string str) {
// Something here
}
}
You can use this builder (test included):
class UrlBuilder2<T> {
private readonly Expression<Func<T, object>> callExpression;
public UrlBuilder2(Expression<Func<T,object>> callExpression) {
this.callExpression = callExpression;
}
public override string ToString() {
MethodCallExpression call = (MethodCallExpression) callExpression.Body;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}/{1}.aspx", call.Object.Type.Name, call.Method.Name);
var delimiter = "?";
var formalParams = call.Method.GetParameters();
for (int i = 0; i < formalParams.Length; i++) {
var actual = call.Arguments[i];
if (actual == null)
continue; // Do not put NULL to QueryString
var formal = formalParams[i].Name;
sb.AppendFormat("{0}{1}={2}", delimiter, formal, HttpUtility.HtmlEncode(actual.ToString()));
}
return sb.ToString();
}
}
[Test]
public void CanBuildUrlByClassAndMethodName() {
var str = new UrlBuilder2<MyForm>(c => c.MyMethod()).ToString();
str.Should().Be.EqualTo("MyForm/MyMethod.aspx");
}
[Test]
public void CanBuildUrlByMethodWithParams() {
var str = new UrlBuilder2<MyForm>(c => c.MethodWithParams(2, "hello")).ToString();
str.Should().Be.EqualTo("MyForm/MyMethod.aspx?i=2&str=hello");
}
All this will allow you to keep the links type-safe and refactoring advantages will be leveraged.
You will probably need to enhance the UrlBuilder2 but this should get you started.
If you just want to use name of a method to generate links you can do something like this:
class MyClass {
public void MyMethod() {}
}
class UrlBuilder3<T> {
Expression<Func<T, Action>> info;
public UrlBuilder3(Expression<Func<T, Action>> info) {
this.info = info;
}
public override string ToString() {
UnaryExpression exp = (UnaryExpression)info.Body;
MethodCallExpression createDelegate = (MethodCallExpression)exp.Operand;
// 0-Action,1-x,2-Delegate as Constant
ConstantExpression methodArgument = (ConstantExpression)createDelegate.Arguments[2];
MethodInfo method = (MethodInfo)methodArgument.Value;
return string.Format("{0}/{1}.aspx", typeof(T).Name, method.Name);
}
}
[Test]
public void UrlByDelegate() {
new UrlBuilder3<MyClass>(x => x.MyMethod).ToString()
.Should().Be.EqualTo("MyClass/MyMethod.aspx");
}
The tricky thing is correctly resolving the Expression tree. The code above works for this particular sample, but you will need to check it works for all your cases.
You can return a function pointer aka a delegate in c# as below.
public delegate int mydelegate(string s);
public class Test
{
mydelegate MyFunc(string s)
{
return (astring => astring.Length + s.Length);
}
}
This would allow you to attach the output of the function to an event.
var test = new Test();
someevent += test.MyFunc("this is a test");
Assuming that someevent took a function with the same signature as the delegate.

Categories