How to make a function private to a method? - c#

I'm working on a method that needs to repeat a small operation at different spots, but the code to be repeated should be private to the method. The obvious solution is a nested function. Whatever I try however, the C# compiler barfs at me.
Something roughly equal to this Perl snippet:
my $method = sub {
$helper_func = sub { code to encapsulate };
# more code
&$helper( called whenever needed );
# more code
}
is what I am talking about, and what I'm trying to accomplish in C#.
No other method in the class should be able to access the helper function in this context. The most logical means of writing this construct in C#, as it appears to me would be something like this:
var helper = (/* parameter names */) => { /* code to encapsulate */ };
And actually make the compiler earn its keep.
Since such an assignment is forbidden, as is the equivalent using the older delegate(){} syntax in place of the lambda, and so is declaring a delegate type within a method—what csc actually allows me to write however, is this:
private delegate /* return type */ Helper(/* parameters */);
private /* return type */ method(/* parameters */) {
Helper helper = (/* parameter names */) => {
/* code to encapsulate */
};
// more code
helper( /* called whenever needed */ );
// more code
}
Which is all fine and dandy for not copy and pasting a chunk of code around and editing the parameters by hand but it leaks a private delegate type to the rest of the class rather than keeping it private to the method. Which defeats the purpose in the first place. Using goto statements and local variables for parameters would provide better encapsulation of "helper" in this context without sacrificing code reuse. If I wanted to simulate function calls by passing parameters through registers, I think would rather use an assembler. I haven't found an acceptable way of refactoring the code to avoid the problem altogether either.
So, is it even possible to force this Common Object Oriented Language to obey?

You actually can do this in C#.
Func<T1, T2, ..., TReturn> myFunc = (a, b, ...) =>
{
//code that return type TReturn
};
If you need an anonymous method of return type void use Action instead of Func:
Action<T1, T2, ...> myAction = (a, b, ...) =>
{
//code that doesn't return anything
};

If you are in C# 3.5 or higher you can take advantage of the lambdas and convenience delegate declarations Func<> and Action<>. So for instance
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
The reason you can't do
var addOne = (ii) => ii +1;
is because of Homoiconicity, the lambda can be interpreted as two different constructs, a delegate and an expression tree. Thus the need to be explicit in declaration.

If you explicitly type it, it will work, i.e.
Action<paramType1, paramType2> helperAction = (/* parameter names */) => { /* code to encapsulate */ };
Func<paramType1, paramType2, returnType> helperFunction = (/* parameter names */) => { /* code to encapsulate */ };
The reason var doesn't work is that a lambda expression can evaluate to multiple types (I believe either a delegate or expression tree, but don't quote me on that) and the compiler in this situation is unable to infer which was meant.

I recommend looking at the Action<T> and Func<TResult> delegates and their overloads. You can do something like this
static void Main(string[] args)
{
SomeMethod();
}
private static void SomeMethod()
{
Action<int> action = (num) => Console.WriteLine(num);
Enumerable.Range(1,10).ToList().ForEach(action);
Console.ReadKey();
}
Here SomeMethod is private and has a local Action<int> delgate that takes an int and does something to it.
I think the issue that you came across is that you can't use implicit typing (i.e. use var) when assigning a lambda expression to a variable.

You can't use the var keyword with lambdas or delegates because they both require additional context information (delegates require a return type, and lambdas require a return type and parameter types). For instance, the (params) => { code } syntax requires to be able to infer the parameter types and return types to work: you do this by explicitly giving it a type.
The generic System.Action delegate type (returns void) could do a good job at what you're trying:
Action<ArgumentType1, ArgumentType2, ...> myDelegate = (params) => { code };
Otherwise, there's also the System.Func, which has a return type, that must be passed as the last generic argument.

It depends on what your definition of hiding is.
The func/action solution (like the one Scott suggests)
void DoSomething()
{
Func<int,int> addOne = (ii) => ii +1;
var two = addOne(1);
}
Feals like hidding the method definition when writing regular C# code BUT is when looking at the IL equivalent of
//This is pseudo code but comes close at the important parts
public class Class1
{
//The actual type is different from this
private static Func<int, int> myMethod = AnonymousFunction;
public void f()
{
myMethod(0);
}
private static int AnonymousFunction(int i)
{
return 1;
}
}
So if you really want to get to the method from outside of the one "hidding" it you can do this with reflection The actual name generated for the field storing the delegate is illegal in C# bul valid in CLR context but that's the only thing that stand in the way of using the delegate as a regular delegate stored in a field (that is if you figue out the name :) )

It's quite simple actually. As the Method seems to have another responsibility than your current Class (why else would you hide this method) move your method into it's own Class and the part you want to have private into a private method in the new class.

Related

What is this line? X = Y => Z(Y)

I was reading about Web API 2 and Entity Framework where I bumped across this line:
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
I looked up the => operator and found that it has something to do with lambdas, although I'm still not sure exactly how it fits in or what's going on here. Can anybody help me out? What's going on in this line?
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
Basically means:
this.Database.Log = blah;
void blah(string s)
{
System.Diagnostics.Debug.WriteLine(s);
}
Database.Log is of the type Action<T>, which is a delegate type
See the property on MSDN
See Action<T> on MSDN
See delegates on MSDN
See lamdas on MSDN
So when this.Database wants to log stuff, it'll call it's "Log" property which is an Action<string>. Since it's an Action<string> (and more importantly, Action<T> is a delegate type), you can assign either a method which returns no value and has a single parameter (which is a string) or a lamda with a single parameter (also, string) (and no return value).
The Database.Log property is of type Action<string>. That means it's a delegate that takes a string and has no return value (i.e. its return type is void). So this line assigns the to the Log property an anonymous function which accepts a string value and writes it to the debugger window.
Because you're assigning the lambda expression to a property with a known delegate type, the compiler can infer the type of the argument (s) and return type from the context. This is shorthand for
this.Database.Log = (delegate (string s){ System.Diagnostics.Debug.WriteLine(s); });
Which in turn is short hand for (as the other answers mention) creating a private method and assigning a delegate reference to that private method:
this.Database.Log = (Action<string>)__compiler_generated_function__;
private void __compiler_generated_function__(string s) {
System.Diagnostics.Debug.WriteLine(s);
}
It means assign a function to this.Database.Log. When this.Database.Log executes it finds the function
s => System.Diagnostics.Debug.WriteLine(s);
That stands for
void LogMethod(string s)
{
System.Diagnostics.Debug.WriteLine(s);
}

Explanation on this code with delegates

I read quite some articles about delegates, and yes, at first the syntax is confusing. I found this article the most useful. Example 2 makes it quite understandable how to use delegates. But I have this code given to me and have work with it:
public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);
class IntList : List<int>
{
public IntList(params int[] elements) : base(elements)
{
}
public void Act(IntAction f)
{
foreach (int i in this)
{
f(i);
}
}
public IntList Filter(IntPredicate p)
{
IntList res = new IntList();
foreach (int i in this)
if (p(i))
res.Add(i);
return res;
}
}
Now, what confuses me here is the f and p variables in the Act and Filter functions. As in the tutorial, those functions seem to be normal, with normal type of their attributes, but here the attributes are of the delegate functions type and I get confusled.
Can you please enlighten me a bit on this matter?
A delegate is just a type. With the types you're used to (like int, string etc.), when you want to use them, you either use one that is in the framework or you declare your own. You can do exactly the same with delegates - either use a prebuilt one (like System.Action) or declare your own, which is what was done here.
So, in your code snippet, 3 types are declared:
public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);
class IntList : List<int> { ... }
You'll notice that the delegate declarations are on the same level as the class declaration.
When you have a type (like your IntPredicate here), you can then use it for variables or function parameters. The questions now are: how do you set the value of the variable, and what do you do with it then?
With ordinary variables, you just pass in the value. Like this:
string text = "Hello world";
The principle is the same with delegates, but, of course, you have to pass in something that is of the delegate type or something that can be converted to it. You have several options:
Existing method
You can pass in a method, if its signature (that is, the return value and parameters) match those of the delegate. So, you could do this:
void WriteIntAction(int value)
{
Console.WriteLine(value);
}
/* then, in some other method */
IntList intList = new IntList(1,2,3);
intList.Act(WriteIntAction);
Anonymous method
There are several ways to create an anonymous method. I'm going to go with lambda expression, because that is simplest. If you've ever worked with any functional languages, this should be familiar.
IntList intList = new IntList(1,2,3);
intList.Act(x => Console.WriteLine(x));
So, after you have your variable set up with the method you need (whether existing or anonymous), you can simply use the delegate variable as you would any method. This is what this line does:
f(i);
Just be aware that delegate is a reference type, so the value of f here can be null, which will then throw an exception when you try to call a delegate.
TL;DR
A delegate is a type. You can use it in a variable or method parameter. You can pass a method in just using its name or you can create an anonymous method. You can then call the method you passed it by using the variable as you would a method.
You can read more online, for example here: http://msdn.microsoft.com/en-us/library/ms173171.aspx
A delegate type is, for all intents and purposes, just a function (or if you are a C++ user, akin to a function-pointer). In other words, you call them just as if they were a function, which is exactly what the sample code does.
f(i) calls the passed function with the i variable as its sole argument, just as it looks.

What are C# lambda's compiled into? A stackframe, an instance of an anonymous type, or?

What are C# lambda's compiled into? A stackframe, an instance of an anonymous type, or?
I've read this question. Which mostly answers "why" you can't use a lambda when also using implicit type features. But, this question is aimed at answering what construct the compiler produces to actually carry out the code of a lambda. Is it a method call of an anonymous type (something like anonymous types that implement an interface in Java?) or is it just a stack frame with references to closed variables and the accepting the parameter signature? Some lambda's don't close over anything -- so are there then 2 different resulting outputs from the compile.
Assuming you mean "as a delegate", then it still depends :p if it captures any variables (including "this", which may be implicit) then those variables are actually implemented as fields on a compiler-generated type (not exposed anywhere public), and the statement body becomes a method on that capture class. If there are multiple levels of capture, the outer capture is again a field on the inner capture class. But essentially:
int i = ...
Func<int,int> func = x => 2*x*i;
Is like;
var capture = new SecretType();
capture.i = ...
Func<int,int> func = capture.SecretMethod;
Where:
class SecretType {
public int i;
public int SecretMethod(int x) { return 2*x*i; }
}
This is identical to "anonymous methods", but with different syntax.
Note that methods that do not capture state may be implemented as static methods without a capture class.
Expression trees, on the other hand... Are trickier to explain :p
But (I don't have a compiler to hand, so bear with me):
int i = ...
Expression<Func<int,int>> func = x => 2*x*i;
Is something like:
var capture = new SecretType();
capture.i = ...
var p = Expression.Parameter("x", typeof(int));
Expression<Func<int,int>> func = Expression.Lambda<Func<int,int>>(
Expression.Multiply(
Expression.Multiply(Expression.Constant(2),p),
Expression.PropertyOrField(Expression.Constant(capture), "i")
), p);
(except using the non-existent "memberof" construct, since the compiler can cheat)
Expression trees are complex, but can be deconstructed and inspected - for example to translate into TSQL.
Lambda expressions are indeed anonymous functions, but with more versatility. These two articles authored by the MSDN have a lot of information on lambda expressions, how to use them, what precedence the operator => has, what their relation to anonymous functions are, and some advanced suggestions of use.
Lambda Expressions (MSDN)
=> Operator (MSDN)
Here are some examples:
public class C
{
private int field = 0;
public void M()
{
int local = 0;
Func<int> f1 = () => 0;
// f1 is a delegate that references a compiler-generated static method in C
Func<int> f2 = () => this.field;
// f2 is a delegate that references a compiler-generated instance method in C
Func<int> f3 = () => local;
// f3 is a delegate that references an instance method of a compiler-generated nested class in C
}
}
A lambda expression is an unnamed method written in place of delegate istance.
The compiler converts it to either:
A delegate instance
An expression tree, of type Expression<TDelegate> that representing the code inside, in a traversable object model. This allows the lambda expression to be interpreted at runtime.
So the compiler solves lambda expressions moving the expression's code into a private method.

Get Method Name Using Lambda Expression

I'm trying to get the name of a method on a type using a lambda expression. I'm using Windows Identity Foundation and need to define access policies with the type name with namespace as a resource and the method name as the action. Here is an example.
This is the type I would be getting the type name and method name from:
namespace My.OrderEntry {
public class Order {
public void AddItem(string itemNumber, int quantity) {}
}
}
This is how I would like to define the access policy through a DSL:
ForResource<Order>().Performing(o => o.AddItem).AllowUsersHaving(new Claim());
From that statement, I would like to get "My.OrderEntry.Order" as the resource and "AddItem" as the action. Getting the type name with namespace is no problem, but I don't think I can use a lambda for a method like I'm trying to do.
public static IPermissionExp Performing<T>(
this IActionExp<T> exp,
Func<T, delegate???> action) {} //this is where I don't know what to define
Is this sort of thing even possible to do? Is there another way to do this sort of thing without using magic strings?
There are two ways to do this:
1: You could make overloads that take the various Func and Action delegates(eg Expression<Func<T, Func<TParam1,TParam2, TReturn>>. Note that your callers would need to specify the generic parameters explicitly, either in the method call or by creating the delegate. This would be used like this:
ForResource<Order>().Performing(o => new Action<string>(o.AddItem)).AllowUsersHaving(new Claim());
2: You could take an Expression<Action> that contains a method call, and parse out the MethodInfo being called from the expression tree. This would be used like this:
ForResource<Order>().Performing(o => { o.AddItem(null); }).AllowUsersHaving(new Claim());
It looks like this is what you are looking for if you want the name of the action delegate method passed in to the Performing function.
public static IPermissionExp Performing<T>(
this IActionExp<T> exp,
Expression<Action<T, string, int>> action)
{
var expression = action.Body as MethodCallExpression;
string actionMethodName = string.Empty;
if (expression != null)
{
actionMethodName = expression.Method.Name;
}
// use actionMethodName ("AddItem" in the case below) here
}
This would allow you to call the method like this...
ForResource<Order>().Performing((o, a, b) => o.AddItem(a, b)).AllowUsersHaving(new Claim());
I recently did a thing at work where you defined the a method using a lambda, which the internal object then took the name of. You could use strings as well, or pass in a MethodInfo but the first one isn't really type safe (and typos are a big risk), and the latter is not very elegant.
Basically I had a method like this (this is not the exact method, it is a bit more advanced):
public void SetRequest(Request req, Expression<Func<Service, Func<long, IEnumerable<Stuff>>> methodSelector);
The key here is the "Expression" thing, this lets you "select" a method like this:
SetRequest(req, service => service.SomeMethodTakingLongReturningStuffs);
Method selector is made into a expression tree which you can then fetch different bits of data from. I don't recall exactly what the resulting tree looks like, it also depends on how your lambdas look.
You could pass it in as a Action instead, which doesn't force any return type. It is still a little messy though, because you have to pass some arguments to the method in order for it to compile.

C# (.NET 3.5) Is there any way to get this function name?

I have a function that wraps a call to one of my socket types. If there is an error, I want to be able to print a warning and retry. In the warning, I want to have the method name. However, it was declared as a lambda. Is this even possible?
How I call the function (assume in function called myMain):
SafeSocketCommand(() => this.mySocket.ReadCurrentBuffer());
Basic wrapping function:
protected TResult SafeSocketCommand<TResult>(Func<TResult> socketCommand)
{
TResult retValue = default(TResult);
try
{
retValue = socketCommand();
}
catch (PacketLost)
{
ReportToLogs("Timeout on command '" + socketCommand.Method.Name);
}
return retValue;
}
But socketCommand.Method.Name gives me the calling method (from the Stack Trace?) '< myMain >b__3' and I want the actual function being invoked by socketCommand (mySocket.ReadCurrentBuffer). Is it possible to get this information anywhere, or is it lost due to declaring in a lambda?
EDIT:
I should have mentioned that I use this particular calling convention so that I can use socket based commands of various signatures.
int i = SafeSocketCommand(() => this.mySocket.FunctionReturnsInt())
bool b = SafeSocketCommand(() => this.mySocket.FunctionReturnsBool(string s))
object o = SafeSocketCommand(() => this.mySocket.Complicated(string s, int i, bool b))
It also handles no return type signatures by overloading:
protected void SafeSocketCommand(Action socketCommand)
{
SafeSocketCommand(() => { socketCommand(); return 0; });
}
If you modify your SafeSocketCommand to accept an Expression<Func<TResult>> then you'll get access to an expression tree that represents the body of the lambda, from which you can access the ReadCurrentBuffer call directly.
However, if you do this, you're no longer dealing with a regular anonymous method; to actually call it you'll need to compile the expression tree to code. You may also need to be flexible as to what your code expects to appear inside the lambda's body.
No, because lambda's don't have names; they're anonymous functions. You could get the method name from the last stackframe, though:
new StackFrame(1).GetMethod().Name;
Func<TResult> is just a delegate. Rather than use a lambda, create a method that matches the signature of Func<TResult> and call that. That way, you'll have whatever name you want.
SafeSocketCommand(MyNewMethod);
...
public TResult MyNewMethod()
{
return this.mySocket.ReadCurrentBuffer();
}
In this case, you can simply this call instead. It'll be faster and smaller generated code too.
SafeSocketCommand(mySocket.ReadCurrentBuffer);
In general, the StackTrace of the Exception object contains the full information you are looking for, much more accurately than printing the method name, or you can use the TargetSite property for the name of the method that threw the exception.

Categories