Can anyone tell me how I can implement Call By Name in C#?
Asked
Active
Viewed 7,282 times
5
-
What version of C# are you using (what is you Visual Studio version)? – Dirk Vollmar Oct 25 '10 at 22:01
-
A compiler in C#, who'd of thunk it! – Byron Whitlock Oct 25 '10 at 22:01
-
@0xA3: It doesn't matter, it should be like a compiler or something like that... – Dr TJ Oct 25 '10 at 22:04
-
@Dr TJ: How would that not matter when you ask about an *implementation*? Different versions of C# have different features available. – Dirk Vollmar Oct 25 '10 at 22:06
-
@0xA3: because this is just about algorithm and I can't use any compilers ability... Just i have to do implementations in one programming language – Dr TJ Oct 25 '10 at 22:09
-
2@Dr TJ: Yes, and C# 4.0 is a different programming language than C# 2.0, complete with different, improved capabilities for handling precisely this issue. – Steven Sudit Oct 25 '10 at 22:53
-
Do you want to use C# as if it were a call-by-name language or do you want to implement a language that uses call-by-name in C#? The "compiler-theory" tag makes it look like the latter, but everyone seems to have answered the former. – sepp2k Oct 26 '10 at 10:33
5 Answers
9
Pass a lambda function instead of a value. C# is eagerly evaluated so in order to defer execution so that each site re-evaluates the supplied arguments you need to wrap the arguments in a function.
int blah = 1;
void Foo(Func<int> somethingToDo) {
int result1 = somethingToDo(); // result1 = 100
blah = 5;
int result2 = somethingToDo(); // result = 500
}
Foo(() => blah * 100);
You can use the Lazy class if you're in .NET 4.0 to get a similar (but not identical) effect. Lazy
memoizes the result so that repeated accesses do not have to re-evaluate the function.

Ron Warholic
- 9,994
- 31
- 47
-
3To those who are wondering, using `Lazy
` will result in *call-by-need*. – porges Oct 25 '10 at 22:32 -
-
2@Steven: Indeed, however strictly speaking lambdas are not delegates but implicitly convertible to matching delegate types. – Ron Warholic Oct 25 '10 at 22:43
-
That distinction would matter if we were to manipulate it as an expression tree, but doesn't happen to make any difference here. – Steven Sudit Oct 25 '10 at 22:50
3
public enum CallType
{
/// <summary>
/// Gets a value from a property.
/// </summary>
Get,
/// <summary>
/// Sets a value into a property.
/// </summary>
Let,
/// <summary>
/// Invokes a method.
/// </summary>
Method,
/// <summary>
/// Sets a value into a property.
/// </summary>
Set
}
/// <summary>
/// Allows late bound invocation of
/// properties and methods.
/// </summary>
/// <param name="target">Object implementing the property or method.</param>
/// <param name="methodName">Name of the property or method.</param>
/// <param name="callType">Specifies how to invoke the property or method.</param>
/// <param name="args">List of arguments to pass to the method.</param>
/// <returns>The result of the property or method invocation.</returns>
public static object CallByName(object target, string methodName, CallType callType, params object[] args)
{
switch (callType)
{
case CallType.Get:
{
PropertyInfo p = target.GetType().GetProperty(methodName);
return p.GetValue(target, args);
}
case CallType.Let:
case CallType.Set:
{
PropertyInfo p = target.GetType().GetProperty(methodName);
p.SetValue(target, args[0], null);
return null;
}
case CallType.Method:
{
MethodInfo m = target.GetType().GetMethod(methodName);
return m.Invoke(target, args);
}
}
return null;
}

Jeremy Thompson
- 61,933
- 36
- 195
- 321
2
You can do that using Reflection:
using System; using System.Reflection; class CallMethodByName { string name; CallMethodByName (string name) { this.name = name; } public void DisplayName() // method to call by name { Console.WriteLine (name); // prove we called it } static void Main() { // Instantiate this class CallMethodByName cmbn = new CallMethodByName ("CSO"); // Get the desired method by name: DisplayName MethodInfo methodInfo = typeof (CallMethodByName).GetMethod ("DisplayName"); // Use the instance to call the method without arguments methodInfo.Invoke (cmbn, null); } }

fresskoma
- 25,481
- 10
- 85
- 128
-
5This is not call-by-name. http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name – Ron Warholic Oct 25 '10 at 22:00
-
5The OP most likely refers to http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_name which is different from dynamically calling a method based on the name. – Dirk Vollmar Oct 25 '10 at 22:03
-
Given they accepted this answer, I suspect the OP was actually referring to VB.NET's [CallByName](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.interaction.callbyname) – isedwards Jan 28 '18 at 14:39
1
If you mean this, then I think the closest equivalent would be delegates.

Steven Sudit
- 19,391
- 1
- 51
- 53