Using a Local Function over an Action as an input param - c#

I have a method that is taking in an Action<string> (see simple example below), but in the calling method where the Action is constructed, Resharper is suggesting that a Local Function should be used.
What are the recommended practices around using Local Functions in place of Actions, does it matter, or are there gotchas to be aware of?
public void Caller()
{
string holder;
Action<string> act = s => holder = s;
void SetHolder(string s) => holder = s;
DoStuff(act);
DoStuff(SetHolder);
}
public void DoStuff(Action<string> setHolder)
{
setHolder("holders new string");
}

Taking you code and putting it through sharplab.io, we can see that the code gets lowered to:
public class Class
{
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0
{
public string holder;
internal void <Caller>b__0(string s)
{
this.holder = s;
}
internal void <Caller>g__SetHolder1(string s)
{
this.holder = s;
}
}
public void Caller()
{
Class.<>c__DisplayClass0_0 #object = new Class.<>c__DisplayClass0_0();
Action<string> setHolder = new Action<string>(#object.<Caller>b__0);
this.DoStuff(setHolder);
this.DoStuff(new Action<string>(#object.<Caller>g__SetHolder1));
}
public void DoStuff(Action<string> setHolder)
{
setHolder("holders new string");
}
}
Because both act and SetHolder are closures over holder, when Caller is invoked a new closure class instance is created and new Action delegates are created for both the lambda and the local function. So the resultant code is identical for both.
Therefore, given the way you are using them here, it just comes down to readability (as many R# recommendations do). Local functions arguably have better syntax, so R# recommends you use it that way.

One of the benefits of local functions over delegates are that invoking them does not incur in a delegate instantiation and delegate invocation which is lost in your example because you are wrapping it with a delegate to pass it to DoStuff.
Have a look at the documentation to know all about local functions.

Related

Guard object in C#

In C++, it's fairly easy to write a Guard class which takes a reference to a variable (usually a bool) and when the instance object exits scope and gets destructed, the destructor resets the variable to the original value.
void someFunction() {
if(!reentryGuard) {
BoolGuard(&reentryGuardA, true);
// do some stuff that might cause reentry of this function
// this section is both early-exit and exception proof, with regards to restoring
// the guard variable to its original state
}
}
I'm looking for a graceful way to do this in C# using the disposal pattern (or maybe some other mechanism?) I'm thinking that passing a delegate to call might work, but seems a bit more error-prone than the guard above. Suggestions welcome!
Something like:
void someFunction() {
if(!reentryGuard) {
using(var guard = new BoolGuard(ref reentryGuard, true)) {
// do some stuff that might cause reentry of this function
// this section is both early-exit and exception proof, with regards to restoring
// the guard variable to its original state
}
}
}
With the understanding that the above code won't work.
You are correct…without unsafe code, you can't save the address of a by-ref parameter. But, depending on how much you can change the overall design, you can create a "guardable" type, such that it's a reference type containing the value to actually guard.
For example:
class Program
{
class Guardable<T>
{
public T Value { get; private set; }
private sealed class GuardHolder<TGuardable> : IDisposable where TGuardable : Guardable<T>
{
private readonly TGuardable _guardable;
private readonly T _originalValue;
public GuardHolder(TGuardable guardable)
{
_guardable = guardable;
_originalValue = guardable.Value;
}
public void Dispose()
{
_guardable.Value = _originalValue;
}
}
public Guardable(T value)
{
Value = value;
}
public IDisposable Guard(T newValue)
{
GuardHolder<Guardable<T>> guard = new GuardHolder<Guardable<T>>(this);
Value = newValue;
return guard;
}
}
static void Main(string[] args)
{
Guardable<int> guardable = new Guardable<int>(5);
using (var guard = guardable.Guard(10))
{
Console.WriteLine(guardable.Value);
}
Console.WriteLine(guardable.Value);
}
}
Here's a functional (as in lambda-based) way to do it. Pluses are, no need to use a using:
(note: This is not thread-safe. If you are looking to keep different threads from running the same code simultaneously, look at the lock statement, the monitor, and the mutex)
// usage
GuardedOperation TheGuard = new GuardedOperation() // instance variable
public void SomeOperationToGuard()
{
this.TheGuard.Execute(() => TheCodeToExecuteGuarded);
}
// implementation
public class GuardedOperation
{
public bool Signalled { get; private set; }
public bool Execute(Action guardedAction)
{
if (this.Signalled)
return false;
this.Signalled = true;
try
{
guardedAction();
}
finally
{
this.Signalled = false;
}
return true;
}
}
EDIT
Here is how you could use the guarded with parameters:
public void SomeOperationToGuard(int aParam, SomeType anotherParam)
{
// you can pass the params to the work method using closure
this.TheGuard.Execute(() => TheMethodThatDoesTheWork(aParam, anotherParam);
}
private void TheMethodThatDoesTheWork(int aParam, SomeType anotherParam) {}
You could also introduce overloads of the Execute method that accept a few different variants of the Action delegate, like Action<T> and Action<T1, T2>
If you need return values, you could introduce overloads of Execute that accept Func<T>
Sounds like the sort of thing you'd have to implement yourself - there are no such mechanisms built into C# or the .NET framework, though I did locate a deprecated class Guard on MSDN.
This sort of functionality would likely need to use a Using statement to operate without passing around an Action block, which as you said could get messy. Note that you can only call using against and IDisposable object, which will then be disposed - the perfect trigger for resetting the value of the object in question.
You can derive your object from IDisposable interface and implement it.
In specific case you are presenting here Dispose will be called as soon as you leave using scope.
Example:
public class BoolGuard : IDisposable
{
....
...
public void Dispose()
{
//DISPOSE IMPLEMANTATION
}
}

Why to use delegates in .Net

I was reading some article which was describing the use of delegates by the following example
which shows the use of multicast delegate
public delegate void ProgressReporter(int percentComplete);
class Program
{
static void Main(string[] args)
{
ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile;
Utility.HardWork();
}
private static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
private static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
public static class Utility
{
public static void HardWork(ProgressReporter p)
{
for (int i = 0; i < 10; i++)
{
p(i);
System.Threading.Thread.Sleep(1000);
}
}
}
But from my understanding of the code I think same can be done using a class and having the same functions which define the tasks done by delegate handlers as follows
public static class ProgressReporter
{
public static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
public static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
and changing the Utility class HardWork() as follows
public static class Utility
{
public static void HardWork()
{
for (int i = 0; i < 10; i++)
{
ProgressReporter.WriteProgressToConsole(i * 10);
ProgressReporter.WriteProgressToFile(i * 10);
System.Threading.Thread.Sleep(1000);
}
}
}
So my question with respect to this code is, why do we actually need a delegate in first place?
Some of the reasons(plz correct if I am wrong) which I think we need the delegate are as follows-
If we need notification in the Program class itself, then we need delegates.
With the help of multicast delegate we can call multiple functions at the same time in place of calling them multiple times(as in my second case).
A delegate is a way to have a reference to a particular method as a variable, meaning it can change, instead of as your last example, hardcoding into the program which methods to call.
Are there way to do this without delegates? Sure, you can provide objects that override methods or use classes that implements interfaces, but delegates are cheaper in the sense that you don't need a whole type wrapped around the single method.
Examples of situations where hardcoding won't do, and interfaces/overriding methods would be more work than delegates, try looking at visual components and their events. Events in .NET use delegates. You can simply double-click on a button in the visual designer in Visual Studio and it will create the method for you and wire it up to the event by the way of a delegate. Having to create a class, or implement an interface on top of the form class would be a lot more work, and especially if you have multiple buttons that you would want to do different things, then you definitely need multiple objects implementing those interfaces.
So delegates have their place, but your examples doesn't do them justice.
Here is a LINQPad example that demonstrates that one method (DoSomething) can end up doing different things depending on the delegate provided to it:
void Main()
{
DoSomething(msg => Console.WriteLine(msg));
using (var writer = new StreamWriter(#"d:\temp\test.txt"))
{
DoSomething(msg => writer.WriteLine(msg));
}
}
public delegate void LogDelegate(string message);
public static void DoSomething(LogDelegate logger)
{
logger("Starting");
for (int index = 0; index < 10; index++)
logger("Processing element #" + index);
logger("Finishing");
}
This will first log to the console, then rerun the method and log to a file.
Use a delegate in the following circumstances
1.An eventing design pattern is used (Event handlers )
2.A class may need more than one implementation of the method
3.Thread implementation (Thread Start, sleep etc )
for more info refer
https://msdn.microsoft.com/en-us/library/ms173173.aspx:

Does C# have a concept of methods inside of methods?

I have been using javascript and I made a lot of use of functions inside of functions. I tried this in C# but it seems they don't exist. If I have the following:
public abc() {
}
How can I code a method d() that can only be called
from inside the method the method abc() ?
I wouldn't worry so much about the restriction of access to a method on the method level but more class level, you can use private to restrict access of the method to that specific class.
Another alternative would be to use lambdas/anonymous methods, or if you're using C# 4.0, Action/Tasks to create them inside your method.
An example of an anonymous method using a delegate (C# 1/2/3/4) for your specific example (incl. I need an action that can take a string parameter and return a string?) would be something like this:
delegate string MyDelegate(string);
public void abc() {
// Your code..
MyDelegate d = delegate(string a) { return a + "whatever"; };
var str = d("hello");
}
.. using C# 3/4:
public void abc() {
// Your code..
Func<string, string> d = (a) => { return a + "whatever"; };
var str = d("hello");
}
.. using a more ideal solution through private method:
private string d(string a)
{
return a + "whatever";
}
public void abc()
{
// Your code..
var str = d("hello");
}
Based on your comment for another answer: I would just like to have this at the bottom of the method and then call it from some earlier code.
This won't be possible, you would need to define a variable for your method using either delegates or Actions and so it would need to be fully initialised by time you call it. You wouldn't then be able to define this at the bottom of your method. A much better option would be to simply create a new private method on your class and call that.
It is not the way to define classes, but you could do:
public abc() {
Action d = () => {
// define your method
};
d();
}
You cannot declare a method inside another method, but you can create anonymous functions inside methods:
public void abc()
{
Action d = () => { ... };
// ...
d();
}
... that can only be called from inside the method the method abc() ?
The method can only be called if you have a reference to it. If you don't store the reference elsewhere then you should be fine.
how can I pass and return a string to the action?
Use a Func instead of an Action:
Func<string, string> d = s => {
return s + "foo";
};
The reason I would like to do this is to make my code more readable.
It's good to try to make your code more readable but I think this change will make it less readable. I suggest you use ordinary methods, and not anonymous functions. You can make them private so that they cannot be called from outside your class.
Use action delegates. More effective than you did.
public abc() {
Action <int> GetInt = (i) =>
{
//Write code here
Console.Writeline("Your integer is: {0}", i);
};
GetInt(10);
}
Action is a delegate so you can give parameter as a method, not variable. Action delegate encapsulates a method that has no parameters and does not return a value. Check it from MSDN.
Yes, they are called delegates and anonymous methods.
Delegate signatures must be predefined outside of the method for the body to be assigned, so it's not exactly like a function. You would first declare a delegate:
class MyClass {
public delegate boolean Decider(string message);
/* ... */
}
And then in MyClass.MyMethod you can say Decider IsAllLowerCase = /* method name or anonymous method */; and then use it with var result = IsAllLowerCase(s);.
The good news is that .NET already has delegate definitions for most signatures you could possibly need. System.Action has assorted signatures for methods which do not return anything, and System.Func is for the ones that do.
As shown elsewhere,
Action<int, string> a = (n, s) => { for(var i=0; i<n; i++) Console.WriteLine(s);};
Allows you to call a( /* inputs */ ); as if it was a local variable. (stuff) => { code } is "lambda expression" or an anonymous method, you can also just pass a name of a method (if the signature matches):
Action<string> a = Console.WriteLine;
If you want to return something, use Func:
Func<bool, string> f = (b) => { return b.ToString(); };
Allows you to call var result = f(b); in the same way.
As a footnote, delegates are a fun part of C#/.NET but usually, the way to control access is to make another method inside your class, and declare it private. If your issue is name conflicts, then you might want to refactor. For example, you can group methods in another class declared inside your original class (nested classes are supported) or move them to another class entirely.
You can use action delegates
public abc() {
Action action = () =>
{
//Your code here
}
action();
}
Edit: To pass parameter
public abc() {
Action <string>action = (str) =>
{
//Your code here
};
}
action("hello");
Using Func to return a value
public void abc() {
Func<string, string> func = (str) => { return "You sent " + str; };
string str = func("hello");
}
You CAN create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
Then yu can call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.

C# function pointer?

I'm having a problem with C#, I'd like to get a pointer of a method in my code, but it seems impossible. I need the pointer of the method because I want to no-op it using WriteProcessMemory. How would I get the pointer?
Example code
main()
{
function1();
function2();
}
function1()
{
//get function2 pointer
//use WPM to nop it (I know how, this is not the problem)
}
function2()
{
Writeline("bla"); //this will never happen because I added a no-op.
}
I know this is very old, but an example of something like a function pointer in C# would be like this:
class Temp
{
public void DoSomething() {}
public void DoSomethingElse() {}
public void DoSomethingWithAString(string myString) {}
public bool GetANewCat(string name) { return true; }
}
...and then in your main or wherever:
var temp = new Temp();
Action myPointer = null, myPointer2 = null;
myPointer = temp.DoSomething;
myPointer2 = temp.DoSomethingElse;
Then to call the original function,
myPointer();
myPointer2();
If you have arguments to your methods, then it's as simple as adding generic arguments to your Action:
Action<string> doItWithAString = null;
doItWithAString = temp.DoSomethingWithAString;
doItWithAString("help me");
Or if you need to return a value:
Func<string, bool> getACat = null;
getACat = temp.GetANewCat;
var gotIt = getACat("help me");
EDIT: I misread your question and didn't see the bit about wanting to NOP a statement with doing raw memory manipulation. I'm afraid this isn't recommended because, as Raymond Chen says, the GC moves stuff around in memory (hence the 'pinned' keyword in C#). You probably can do it with reflection, but your question suggests you don't have a strong grasp of the CLR. Anyway, back to my original irrelevant answer (where I thought you just wanted information on how to use delegates):
C# isn't a scripting language ;)
Anyway, C# (and the CLR) has "function pointers" - except they're called "delegates" and are strongly typed, which means you need to define the function's signature in addition to the function you want to call.
In your case, you'd have something like this:
public static void Main(String[] args) {
Function1();
}
// This is the "type" of the function pointer, known as a "delegate" in .NET.
// An instance of this delegate can point to any function that has the same signature (in this case, any function/method that returns void and accepts a single String argument).
public delegate void FooBarDelegate(String x);
public static void Function1() {
// Create a delegate to Function2
FooBarDelegate functionPointer = new FooBarDelegate( Function2 );
// call it
functionPointer("bla");
}
public static void Function2(String x) {
Console.WriteLine(x);
}
public string myFunction(string name)
{
return "Hello " + name;
}
public string functionPointerExample(Func<string,string> myFunction)
{
return myFunction("Theron");
}
Func functionName.. use this to pass methods around. Makes no sense in this context but thats basically how you would use it
I'd wish it is useful
class Program
{
static void Main(string[] args)
{
TestPointer test = new TestPointer();
test.function1();
}
}
class TestPointer
{
private delegate void fPointer(); // point to every functions that it has void as return value and with no input parameter
public void function1()
{
fPointer point = new fPointer(function2);
point();
}
private void function2()
{
Console.WriteLine("Bla");
}
}
Actually there are real function pointers introduced in C# 9
Official Documentation
From the link:
You can define a function pointer using the delegate* syntax. The compiler will call the function using the calli instruction rather than instantiating a delegate object and calling Invoke
Example for the example in the post:
static unsafe void function1()
{
//get function2 pointer
delegate*<void> ptr = &function2;
// do something with ptr
}
Rewriting a method cannot be done directly from managed code, however the unmanaged .net profiling api can be used to do this. See this msdn article for example on how to use it.

C#: Creating an instance of an abstract class without defining new class

I know it can be done in Java, as I have used this technique quite extensively in the past. An example in Java would be shown below. (Additional question. What is this technique called? It's hard to find an example of this without a name.)
public abstract class Example {
public abstract void doStuff();
}
public class StartHere{
public static void main(string[] args){
Example x = new Example(){
public void doStuff(){
System.out.println("Did stuff");
}
};
x.doStuff();
}
}
Now, my main question would be, can this also be done in C#, and if so, how?
The Java technique is called "Anonymous inner class", and there is no equivalent in C#.
With lamba expressions and class initializers you can get the same behaviour with a bit of effort.
public class Example {
public Action DoStuff;
public Action<int> DoStuffWithParameter;
public Func<int> DoStuffWithReturnValue;
}
class Program {
static void Main(string[] args) {
var x = new Example() {
DoStuff = () => {
Console.WriteLine("Did Stuff");
},
DoStuffWithParameter = (p) => {
Console.WriteLine("Did Stuff with parameter " + p);
},
DoStuffWithReturnValue = () => { return 99; }
};
x.DoStuff();
x.DoStuffWithParameter(10);
int value = x.DoStuffWithReturnValue();
Console.WriteLine("Return value " + value);
Console.ReadLine();
}
}
One problem with this solution that I just realized is that if you were to create fields in the Example class, the lambda expressions would not be able to access those fields.
However, there is no reason that you could not pass the instance of Example to the lambda expressions which would give them access to any public state that example might hold. AFAIK that would be functionally equivalent to the Java Anonymous Inner Class.
P.S. If you are going to vote an answer down, do us all a favour and add a comment as to why you disagree :-)
Typically, problems that are solved with anonymous inner classes in Java are solved in a much cleaner fashion using delegates in .Net. Your example is a little too simplistic to determine your intent. If your intent by using the abstract class is to pass around a "behavior" think about just using an Action delegate instead.
public class StartHere{
public static void main(string[] args){
Action doStuff = () => Console.WriteLine("Did stuff");
executeSomething(doStuff);
}
public static void executeSomething(Action action)
{
action();
}
}
That can't be done in C#; you need to declare a new class type. The closest you can get in C# is probably a named nested class:
public class StartHere{
private class Foo : Example {
public override void doStuff()
{
Console.WriteLine("did stuff");
}
}
public static void Main(string[] args){
Example x = new Foo();
x.doStuff();
}
}
This is not supported in C#, and if it were up to me it shouldn't be so either.
The proliferation of inner classes in java is mainly due to the lack of delegates or lambdas, which C# has. So while this type of functionality currently is "your only hope" in java, you can usually use other mechanisms in C# to achieve the same ends. Java feels like playing the piano with one hand in this regard.
(Admittedly a lot of us have gotten quite good at this one-handed playing; and now it seems like we have to wait at least until java 8 for closures...)
Since your class represents only an action, you can use a delegate in your case, there is an existing delegate :
public delegate void Action();
This is the exact equivalent of your class.
And the déclaration of your anonymous class is even cleaner :
Action action = () => Console.WriteLine("Hello world");
action(); // invoke
you can even use closure :
public void Hello(string name)
{
Action action = () => Console.WriteLine("Hello " + name);
action(); // will call the above lambda !
}
While all good answers, most of the work arounds suggested rely on C# 3.0
So, for the sake of completeness, I'll add another solution that uses neither lambdas nor Func type (Granted that, as Matt Olenik mentioned in the comments, one could generalize the below delegates to work the same way.). For those, like me who may still be working with C# 2.0. Maybe not the best solution, but it works.
public class Example
{
public delegate void DoStuffDelecate();
public DoStuffDelecate DoStuff;
public delegate void DoStuffWithDelecate(int n);
public DoStuffWithDelecate DoStuffWithParameter;
public delegate int DoStuffWithReturnDelecate();
public DoStuffWithReturnDelecate DoStuffWithReturnValue;
}
class Program
{
static int MethodWithReturnValue()
{
return 99;
}
static void MethodForDelecate()
{
Console.WriteLine("Did Stuff");
}
static void MethodForDelecate(int n)
{
Console.WriteLine("Did Stuff with parameter " + n);
}
static void Main(string[] args)
{
var x = new Example();
x.DoStuff = MethodForDelecate;
x.DoStuffWithParameter = MethodForDelecate;
x.DoStuffWithReturnValue = MethodWithReturnValue;
x.DoStuff();
x.DoStuffWithParameter(10);
int value = x.DoStuffWithReturnValue();
Console.WriteLine("Return value " + value);
Console.ReadLine();
}
}
You are able to accomplish this with Mocking in .NET. However there is no in-language support for this feature, I think it will be available in C# 4.0. There are a number of libraries out there for Mocking, including:
Moq
RhinoMock
In short no, you have to define it as separate sub class. I think this feature is coming C# 4.0 though?
Edit: No it's not coming C# 4.0 I made that up.

Categories

Resources