C# retry method interception with free a AOP framework - c#

I'm totally new to the AOP in C#. Currently, I'm interested to write a retry for a method that uses this technique.
So, based on the postsharp tut: https://doc.postsharp.net/method-interception
I've written this code:
[Serializable]
public class RetryAspect : MethodInterceptionAspect
{
private int _sleep;
private int _retries;
private object _expectedResult;
private object _defaultReturnValue;
public RetryAspect(object expectedResult, int waitBetweenCycles, int numberOfRetries) : this(expectedResult, waitBetweenCycles, numberOfRetries, null) { }
public RetryAspect(object expectedResult, int waitBetweenCycles, int numberOfRetries, object defaultReturnValue)
{
_expectedResult = expectedResult;
_sleep = waitBetweenCycles;
_retries = numberOfRetries;
_defaultReturnValue = defaultReturnValue;
}
public override void OnInvoke(MethodInterceptionArgs args)
{
int waitCount = 0;
while (!args.ReturnValue.Equals(_expectedResult))
{
args.Proceed();
if (waitCount++ < _retries)
{
Thread.Sleep(_sleep);
}
else
{
if (_defaultReturnValue != null)
{
args.ReturnValue = _defaultReturnValue;
}
break;
}
}
}
}
class Program
{
static int cnt = 0;
static void Main(string[] args)
{
Console.WriteLine(Test());
Console.ReadKey();
}
[RetryAspect(true, 1000, 5)]
public static bool Test()
{
Console.WriteLine("Test {0}", cnt);
if (cnt == 4)
{
return true;
}
else
{
cnt++;
return false;
}
}
}
Now, is there a way to achieve the same result by using a free/open source AOP framework? So far, I didn't found any useful example with a different AOP framework.

Althogh it is not AOP I can suggest you to use Polly:
Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry ...
You will just need to define your policy using it's fluent API:
var policy = Policy
.HandleResult<bool>(false)
//Or using one of WaitAndRetry overloads if you want to sleep between retries
.Retry(5);
And execute it:
policy.Execute(() => Test());

Related

Transaction scope similar functionality

I am looking to setup something very similar to transaction scope which creates a version on a service and will delete/commit at the end of scope. Every SQL statement ran inside the transaction scope internally looks at some connection pool / transaction storage to determine if its in the scope and reacts appropriately. The caller doesn't need to pass in the transaction to every call. I am looking for this functionality.
Here is a little more about it: https://blogs.msdn.microsoft.com/florinlazar/2005/04/19/transaction-current-and-ambient-transactions/
Here is the basic disposable class:
public sealed class VersionScope : IDisposable
{
private readonly GeodatabaseVersion _version;
private readonly VersionManager _versionManager;
public VersionScope(Configuration config)
{
_versionManager = new VersionManager(config);
_version = _versionManager.GenerateTempVersion();
_versionManager.Create(_version);
_versionManager.VerifyValidVersion(_version);
_versionManager.ServiceReconcilePull();
_versionManager.ReconcilePull(_version);
}
public void Dispose()
{
_versionManager.Delete(_version);
}
public void Complete()
{
_versionManager.ReconcilePush(_version);
}
}
I want the ability for all the code I've written thus far to not have any concept of being in a version. I just want to include a simple
Version = GetCurrentVersionWithinScope()
at the lowest level of the code.
What is the safest way of implementing something like this with little risk of using the wrong version if there are multiple instances in memory simultaneously running.
My very naive approach would be find if there is a unique identifier for a block of memory a process is running in. Then store the current working version to a global array or concurrent dictionary. Then in the code where I need the current version, I use its block of memory identifier and it maps to the version that was created.
Edit:
Example of usage:
using (var scope = new VersionScope(_config))
{
AddFeature(); // This has no concept of scope passed to it, and could error out forcing a dispose() without a complete()
scope.Complete();
}
The most straightforward approach would be to use ThreadStatic or ThreadLocal to store current version in thread local storage. That way multiple threads will not interfere with each other. For example suppose we version class:
public class Version {
public Version(int number) {
Number = number;
}
public int Number { get; }
public override string ToString() {
return "Version " + Number;
}
}
Then implementation of VersionScope can go like this:
public sealed class VersionScope : IDisposable {
private bool _isCompleted;
private bool _isDisposed;
// note ThreadStatic attribute
[ThreadStatic] private static Version _currentVersion;
public static Version CurrentVersion => _currentVersion;
public VersionScope(int version) {
_currentVersion = new Version(version);
}
public void Dispose() {
if (_isCompleted || _isDisposed)
return;
var v = _currentVersion;
if (v != null) {
DeleteVersion(v);
}
_currentVersion = null;
_isDisposed = true;
}
public void Complete() {
if (_isCompleted || _isDisposed)
return;
var v = _currentVersion;
if (v != null) {
PushVersion(v);
}
_currentVersion = null;
_isCompleted = true;
}
private void DeleteVersion(Version version) {
Console.WriteLine($"Version {version} deleted");
}
private void PushVersion(Version version) {
Console.WriteLine($"Version {version} pushed");
}
}
It will work, but it will not support nested scopes, which is not good, so to fix we need to store previous scope when starting new one, and restore it on Complete or Dispose:
public sealed class VersionScope : IDisposable {
private bool _isCompleted;
private bool _isDisposed;
private static readonly ThreadLocal<VersionChain> _versions = new ThreadLocal<VersionChain>();
public static Version CurrentVersion => _versions.Value?.Current;
public VersionScope(int version) {
var cur = _versions.Value;
// remember previous versions if any
_versions.Value = new VersionChain(new Version(version), cur);
}
public void Dispose() {
if (_isCompleted || _isDisposed)
return;
var cur = _versions.Value;
if (cur != null) {
DeleteVersion(cur.Current);
// restore previous
_versions.Value = cur.Previous;
}
_isDisposed = true;
}
public void Complete() {
if (_isCompleted || _isDisposed)
return;
var cur = _versions.Value;
if (cur != null) {
PushVersion(cur.Current);
// restore previous
_versions.Value = cur.Previous;
}
_isCompleted = true;
}
private void DeleteVersion(Version version) {
Console.WriteLine($"Version {version} deleted");
}
private void PushVersion(Version version) {
Console.WriteLine($"Version {version} pushed");
}
// just a class to store previous versions
private class VersionChain {
public VersionChain(Version current, VersionChain previous) {
Current = current;
Previous = previous;
}
public Version Current { get; }
public VersionChain Previous { get; }
}
}
That's already something you can work with. Sample usage (I use single thread, but if there were multiple threads doing this separately - they will not interfere with each other):
static void Main(string[] args) {
PrintCurrentVersion(); // no version
using (var s1 = new VersionScope(1)) {
PrintCurrentVersion(); // version 1
s1.Complete();
PrintCurrentVersion(); // no version, 1 is already completed
using (var s2 = new VersionScope(2)) {
using (var s3 = new VersionScope(3)) {
PrintCurrentVersion(); // version 3
} // version 3 deleted
PrintCurrentVersion(); // back to version 2
s2.Complete();
}
PrintCurrentVersion(); // no version, all completed or deleted
}
Console.ReadKey();
}
private static void PrintCurrentVersion() {
Console.WriteLine("Current version: " + VersionScope.CurrentVersion);
}
This however will not work when you are using async calls, because ThreadLocal is tied to a thread, but async method can span multiple threads. However, there is similar construct named AsyncLocal, which value will flow through asynchronous calls. So we can add constructor parameter to VersionScope indicating if we need async flow or not. Transaction scope works in a similar way - there is TransactionScopeAsyncFlowOption you pass into TransactionScope constructor indicating if it will flow through async calls.
Modified version looks like this:
public sealed class VersionScope : IDisposable {
private bool _isCompleted;
private bool _isDisposed;
private readonly bool _asyncFlow;
// thread local versions
private static readonly ThreadLocal<VersionChain> _tlVersions = new ThreadLocal<VersionChain>();
// async local versions
private static readonly AsyncLocal<VersionChain> _alVersions = new AsyncLocal<VersionChain>();
// to get current version, first check async local storage, then thread local
public static Version CurrentVersion => _alVersions.Value?.Current ?? _tlVersions.Value?.Current;
// helper method
private VersionChain CurrentVersionChain => _asyncFlow ? _alVersions.Value : _tlVersions.Value;
public VersionScope(int version, bool asyncFlow = false) {
_asyncFlow = asyncFlow;
var cur = CurrentVersionChain;
// remember previous versions if any
if (asyncFlow) {
_alVersions.Value = new VersionChain(new Version(version), cur);
}
else {
_tlVersions.Value = new VersionChain(new Version(version), cur);
}
}
public void Dispose() {
if (_isCompleted || _isDisposed)
return;
var cur = CurrentVersionChain;
if (cur != null) {
DeleteVersion(cur.Current);
// restore previous
if (_asyncFlow) {
_alVersions.Value = cur.Previous;
}
else {
_tlVersions.Value = cur.Previous;
}
}
_isDisposed = true;
}
public void Complete() {
if (_isCompleted || _isDisposed)
return;
var cur = CurrentVersionChain;
if (cur != null) {
PushVersion(cur.Current);
// restore previous
if (_asyncFlow) {
_alVersions.Value = cur.Previous;
}
else {
_tlVersions.Value = cur.Previous;
}
}
_isCompleted = true;
}
private void DeleteVersion(Version version) {
Console.WriteLine($"Version {version} deleted");
}
private void PushVersion(Version version) {
Console.WriteLine($"Version {version} pushed");
}
// just a class to store previous versions
private class VersionChain {
public VersionChain(Version current, VersionChain previous) {
Current = current;
Previous = previous;
}
public Version Current { get; }
public VersionChain Previous { get; }
}
}
Sample usage of scopes with async flow:
static void Main(string[] args) {
Test();
Console.ReadKey();
}
static async void Test() {
PrintCurrentVersion(); // no version
using (var s1 = new VersionScope(1, asyncFlow: true)) {
await Task.Delay(100);
PrintCurrentVersion(); // version 1
await Task.Delay(100);
s1.Complete();
await Task.Delay(100);
PrintCurrentVersion(); // no version, 1 is already completed
using (var s2 = new VersionScope(2, asyncFlow: true)) {
using (var s3 = new VersionScope(3, asyncFlow: true)) {
PrintCurrentVersion(); // version 3
} // version 3 deleted
await Task.Delay(100);
PrintCurrentVersion(); // back to version 2
s2.Complete();
}
await Task.Delay(100);
PrintCurrentVersion(); // no version, all completed or deleted
}
}
private static void PrintCurrentVersion() {
Console.WriteLine("Current version: " + VersionScope.CurrentVersion);
}
Use of IDisposable like this is somewhat questionable. (See Is it abusive to use IDisposable and "using" as a means for getting "scoped behavior" for exception safety?)
I, myself find it useful for some things. This is a pattern I use:
class LevelContext
{
private int _level;
public int CurrentLevel
{
get { return _level; }
set { _level = value < 0 ? 0 : value; }
}
public ILevel NewLevel(int depth = 1)
{
return new Level(this, depth);
}
/// <summary>
/// Provides an interface that calling code can use to handle level objects.
/// </summary>
public interface ILevel : IDisposable
{
LevelContext Owner { get; }
int Depth { get; }
void Close();
}
/// <summary>
/// Private class that provides an easy way to scope levels by allowing
/// them to participate in the "using" construct. Creation of a Level results in an
/// increase in owner's level, while disposal returns owner's level to what it was before.
/// </summary>
class Level : ILevel
{
public Level(LevelContext owner, int depth)
{
Owner = owner;
Depth = depth;
PreviousLevel = owner.CurrentLevel;
Owner.CurrentLevel += Depth;
}
public LevelContext Owner { get; private set; }
public int Depth { get; private set; }
public int PreviousLevel { get; private set; }
public void Close()
{
if (Owner != null)
{
Owner.CurrentLevel = PreviousLevel;
Owner = null;
}
}
void IDisposable.Dispose()
{
Close();
}
}
Then the calling code looks like this:
static void Main(string[] args)
{
var lc = new LevelContext();
Console.WriteLine(lc.CurrentLevel);
using (lc.NewLevel())
Console.WriteLine(lc.CurrentLevel);
Console.WriteLine(lc.CurrentLevel);
}
So in your case, you are correct - you need to create something that tracks the current version. That something should get updated when VersionScopes are created and disposed.

How to implement IDisposable pattern for a serial connection wrapper

I am designing a C# library that uses FTDI library to manage FTDI devices and their connections. I model it in three levels of operations:
1. Enumerate plugged devices;
2. Open/Close a connection to a specific device;
3. Write to the device, and receive bytes from it.
Currently I have the following classes:
public static class FtdiEnumerator
{
public static IEnumerable<FtdiDevice> Enumerate()
{
FTDI ftdi = new FTDI();
FTDI.FT_STATUS status;
uint bufferLenght = 0;
status = ftdi.GetNumberOfDevices(ref bufferLenght);
FTDI.FT_DEVICE_INFO_NODE[] result = new FTDI.FT_DEVICE_INFO_NODE[bufferLenght];
if (status != FTDI.FT_STATUS.FT_OK)
return Enumerable.Empty<FtdiDevice>();
status = ftdi.GetDeviceList(result);
if (status != FTDI.FT_STATUS.FT_OK)
return Enumerable.Empty<DispositivoFtdi>();
return result.Where(node => node != null)
.Select(node => new DispositivoFtdi(node))
.ToArray(); ;
}
}
public class FtdiDevice
{
protected FT_DEVICE_INFO_NODE _node;
protected FTDI _ftdi = new FTDI();
public string Description => _node.Description;
public string SerialNumber => _node.SerialNumber;
public FtdiDevice(FT_DEVICE_INFO_NODE node)
{
_node = node;
}
public void Open(uint baudRate = 115200)
{
FT_STATUS status = _ftdi.OpenBySerialNumber(_node.SerialNumber);
if (status != FT_STATUS.FT_OK)
throw new Exception();
status = _ftdi.SetBaudRate(baudRate);
if (status != FT_STATUS.FT_OK)
throw new Exception()
}
public void Close()
{
_ftdi.Close();
}
public void Write(byte[] bytes)
{
uint bytesReceived = 0;
_ftdi.Write(bytes, bytes.Length, ref bytesReceived);
}
}
I know about the IDisposable pattern, and I see a clear use case for it here, regarding FtdiDevice.Open() and FtdiDevice.Close() methods, but I see that usually the pattern is implemented with another, additional class. I imagine something like a FtdiConnection class, to be used like this, I think:
var device = new FtdiDevice(node);
using (FtdiConnection connection = device.Open())
{
connection.Write(bytes);
}
That would imply moving the Write(byte[] bytes) method to this FtdiConnection class.
I am not sure if I am in the right track, or how much sense my idea makes, and would appreciate any clarification.
I think what you want to do this:
public class FtdiConnection : IDisposable
{
private FtdiDevice device;
public FtdiConnection(FtdiDevice device)
{
this.device = device;
}
public void Dispose()
{
device.Close();
}
}
into your open method:
public FtdiConnection Open(uint baudRate = 115200)
{
... Open ...
return new FtdiConnection(this);
}
and use like
var device = new FtdiDevice(node);
using (FtdiConnection connection = device.Open())
{
connection.Write(bytes);
}
I found out, inspired on the discussion and previous answer, the following design answers my needs. I will add it here as an alternative to Gustavo's answer, and would be glad to know other alternatives.
The solution principle here is to have Device.Open() to return this as the disposable, thus avoiding the need for an additional Connection class:
using System;
namespace DisposableConnection
{
class Program
{
static void Main(string[] args)
{
var device = new Device();
using (device.Open())
{
device.Write();
}
Console.ReadKey();
}
}
public class Device : IDisposable
{
public Device()
{
}
public IDisposable Open()
{
Console.WriteLine("Open!!");
return this;
}
public void Close()
{
Console.WriteLine("Close!!");
}
internal void Write()
{
Console.WriteLine("Write!!");
//throw new Exception(); // optional, also works
}
public void Dispose()
{
Close();
}
}
}

Implement extensibility on callback?

Currently, I am working on an API, and developers can subscribe to it to know the updates.
So right now I am implementing an interface IResult , so that I can send different parameters in the callback result. The problem right now is if in the future, I want to add a new callback, I have to add an argument in the method, and developers also need to change their method call. Is there a good solution for this?
public interface IResult
{
int i { get; set; }
}
public class ConcreteResult : IResult
{
public int i
{
get;set;
}
}
public class MyAPI
{
public delegate void MyAPIDelegate(IResult result);
public void StartService(MyAPIDelegate callback, MyAPIDelegate callback2)
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
callback(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
callback2(result2);
//potentially added in the future
//i += 1;
//callback3();
}
public void main()
{
//developers use my API
StartService(developerCallback, developerCallback2);
}
private void developerCallback(IResult result)
{
Console.WriteLine(result.i);
}
private void developerCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}
Oddly everyone is recommending events, but nobody is showing an example. I'll bite.
Judging by the naming conventions I'm guessing you come from Java land. (C# methods are generally PascalCase). C# has events, which make things like this much simpler. I recommend you study them up, as they're quite common in C# code.
All you have to do is define a public event on your class, and have that class invoke the event where necessary. (do ?. because an unsubscribed event is weirdly null).
Then from the consuming class, you subscribe handlers for it using +=.
This allows you to add new events in the future without your consumers having to worry about it.
public class MyAPI
{
public event Action<IResult> Callback1;
public event Action<IResult> Callback2;
public void StartService()
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
Callback1?.Invoke(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
Callback2?.Invoke(result2);
//potentially added in the future
//i += 1;
//callback3();
}
}
public static class Program {
public static void Main()
{
//developers use my API
var api = new MyAPI();
api.Callback1 += DeveloperCallback;
api.Callback2 += DeveloperCallback2;
api.StartService();
}
private static void DeveloperCallback(IResult result)
{
Console.WriteLine(result.i);
}
private static void DeveloperCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}
Also for simple event handlers, you can subscribe inline:
api.Callback1 += result =>
{
Console.WriteLine(result.i);
};
Or even simpler for one-liners:
api.Callback1 += result => Console.WriteLine(result.i);
Since you asked, another option a bit more heavier than simple events, but eventually more powerful is Reactive Extensions. If you want to use these, then you can write code like this:
using System.Reactive.Subjects;
public class MyAPI
{
private readonly Subject<IResult> callback1 = new Subject<IResult>();
private readonly Subject<IResult> callback2 = new Subject<IResult>();
public void StartService()
{
//step 1
int i = 0;
ConcreteResult result1 = new ConcreteResult();
result1.i = i;
callback1.OnNext(result1);
//step 2
i += 1;
ConcreteResult result2 = new ConcreteResult();
result2.i = i;
callback2.OnNext(result2);
}
public IObservable<IResult> Callback1 => this.callback1;
public IObservable<IResult> Callback2 => this.callback2;
}
public static class Program
{
public static void Main()
{
var api = new MyAPI();
// Subscribing returns a disposable subscription, and disposing it unsubscribes.
// That means you can use lambda syntax and still unsubscribe later
IDisposable subscription =
api.Callback1.Subscribe(result => Console.WriteLine(result.i));
api.StartService(); // Writes result.
// Once disposed, event is no longer called
subscription.Dispose();
api.StartService(); // Doesn't write result.
// Since IDisposable is a special thing that can be scoped to using blocks in C#, you can do the following:
using (api.Callback1.Subscribe(result => Console.WriteLine(result.i)))
{
api.StartService(); // Writes result
}
api.StartService(); // Doesn't write result
}
}
I strongly recommend using events, like #Vikhram suggested, but here is your example, modified to use a class as you requested.
Notice that I did not specify a Callback3 when calling the function. The API uses .? when calling them, instead of just ., so that it doesn't cause a NullReferenceException if the developer doesn't pass one in.
When you add more callbacks, just add additional properties to MyCallbackInfo, and invoke them the same as the existing ones.
public interface IResult {... }
public class ConcreteResult : IResult {...}
public class MyStartServiceCallbackInfo
{
public MyAPI.MyAPIDelegate Callback1 { get; set; }
public MyAPI.MyAPIDelegate Callback2 { get; set; }
public MyAPI.MyAPIDelegate Callback3 { get; set; }
}
public class MyAPI
{
public delegate void MyAPIDelegate(IResult result);
public void StartService(MyStartServiceCallbackInfo callbacks)
{
...
callbacks?.Callback1(result1);
...
callbacks?.Callback2(result2);
...
callbacks?.Callback3(result3);
}
public void main()
{
StartService(new MyCallbackInfo()
{
Callback1 = developerCallback,
Callback2 = developerCallback2,
});
}
private void developerCallback(IResult result)
{
Console.WriteLine(result.i);
}
private void developerCallback2(IResult result)
{
Console.WriteLine(result.i);
}
}

With Delphi/Pascal there are internal methods - isn't there a way of doing that in C# [duplicate]

I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then 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.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}

Method Within A Method

I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then 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.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}

Categories