How to make a function private for a method?

I am working on a method that needs to repeat a small operation in different places, but the code that needs to be repeated must be closed to the method. The obvious solution is a nested function. However, no matter what I try, the C # compiler is on me.

Something roughly equal to this Perl fragment:

my $method = sub { $helper_func = sub { code to encapsulate }; # more code &$helper( called whenever needed ); # more code } 

this is what I'm talking about and what I'm trying to accomplish in C #.

No other method in a class should have access to a helper function in this context. The most logical way to write this construct in C #, it seems to me, would be something like this:

 var helper = (/* parameter names */) => { /* code to encapsulate */ }; 

And actually make the compiler make money.

Since such an assignment is forbidden, like the equivalent using the syntax of the older delegate () {} instead of lambda, and therefore declares the delegate type in the 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 } 

That’s all fine and dandy in order not to copy and paste a piece of code and edit the parameters manually, but it comforts the private type of the delegate for the rest of the class, and does not keep it private for the method. What strikes the target in the first place. Using goto operators and local variables for parameters would provide better encapsulation of the helper in this context without sacrificing code reuse. If I wanted to simulate function calls by passing parameters through registers, I would rather use assembler. I did not find an acceptable way to refactor the code to avoid the problem at all.

So, is it even possible to make this Common Object Oriented Language obey?

+4
source share
7 answers

If you are in C # 3.5 or higher, you can use the lambdas delegate declarations and the convenience of Func<> and Action<> . For example,

 void DoSomething() { Func<int,int> addOne = (ii) => ii +1; var two = addOne(1); } 

The reason you cannot do

 var addOne = (ii) => ii +1; 

Due to homoiconicity , lambda can be interpreted as two different constructs, a delegate and an expression tree. Therefore, it is necessary to be explicit in the declaration.

+6
source

You can really do it in C #.

 Func<T1, T2, ..., TReturn> myFunc = (a, b, ...) => { //code that return type TReturn }; 


If you need an anonymous return method of type void, use Action instead of Func:

 Action<T1, T2, ...> myAction = (a, b, ...) => { //code that doesn't return anything }; 
+8
source

If you explicitly enter 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 does not work, since a lambda expression can be evaluated by several types (I believe that this is either a delegate or an expression tree, but do not quote me on this), and the compiler in this situation cannot be implied.

+4
source

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 Delta Action<int> that accepts an int and does something with it.

I think the problem you are facing is that you cannot use implicit typing (i.e. use var ) when assigning a lambda expression to a variable.

+2
source

You cannot use the var keyword with lambdas or delegates because they require additional context information (delegates require a return type and lambdas a return type and parameter types). For example, the syntax (params) => { code } should be able to output parameter types and return data types to work: you do this by explicitly specifying the type.

The generic delegate type System.Action (returns void ) can do a good job of trying:

 Action<ArgumentType1, ArgumentType2, ...> myDelegate = (params) => { code }; 

Otherwise, there is also System.Func , which has a return type that should be passed as the last common argument.

+1
source

It depends on what your definition of concealment is.

Func / action solution (as prompted by Scott)

 void DoSomething() { Func<int,int> addOne = (ii) => ii +1; var two = addOne(1); } 

It seems like it hides the method definition when writing regular C # code, but when viewing the IL equivalent

 //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; } } 

That way, if you really want to switch to a method because you are hiding it, you can do it with reflection. The actual name generated for the field holding the delegate is illegal in C # bul, valid in the context of the CLR, but that the only thing that stands in the way of using the delegate as a regular delegate stored in the field (that is, if you cross out the name :) )

0
source

It is pretty simple. Since the method seems to have a different responsibility than your current class (why don't you hide this method), move your method to your own class and the part that you want to use in the private method in the new class.

-1
source

All Articles