I have several methods that execute the same setup code and then some cleanup code. The stuff in between changes. I could do it like this:
void method1()
{
var x = DoSetupStuff();
// Method 1 specific code that uses x
DoCleanupStuff(x);
}
void method2()
{
var x = DoSetupStuff();
// Method 2 specific code that uses x
DoCleanupStuff(x);
}
But I'd rather do something where I don't have to call both setup and cleanup methods every time. Maybe like one call where the method specific stuff can be passed in?
void SetupAndCleanup( method-specific-code )
{
// Setup code here
int x = 1;
// method-specific code injected here.
// note that it uses x.
// cleanup code here
x = 0;
}
The method1, method2 approach works perfectly well, I'm just wandering if there is a way to improve it or make it more elegant.
If "x" is always an int you can just pass in an Action:
void SetupAndCleanup( Action<int> methodCode )
{
// Setup code here
int x = 1;
try
{
methodCode(x);
}
finally
{
// cleanup code here
x = 0;
}
}
You can use a delegate:
void SetupAndCleanup(Action action) {
// setup
action();
// cleanup
}
void Method1() {
SetupAndCleanup(() => {
// do my stuff here
});
}
// or...
private void Method2Impl() {
// do my stuff here
}
void Method2() {
SetupAndCleanup(Method2Impl);
}
or an IDisposable:
private sealed class SetupClass : IDisposable {
public SetupClass() {
// setup
}
public void Dispose() {
// cleanup
}
}
void Method1() {
using (SetupClass setup = new SetupClass() {
// do stuff here
}
}
void Method2() {
using (SetupClass setup = new SetupClass() {
// do stuff here
}
}
If you can place the Method1 & Method2 specific code into their own functions, and each could share the same method signature, then create a delegate type of the signature, and write Method1 & Method2 to conform to the signature and pass it to SetupAndCleanup. A lambda will work if you can do everything you need to using the lambda. To use the lambda just remember that the lambda follows the signature of the delegate.
Sounds like you might want to use a class:
public abstract class DoStuff
{
protected abstract void DoStuffImpl(var x);
private var DoSetupStuff()
{
} // eo DoSetupStuff
private void DoCleanupStuff(var x)
{
} // eo DoCleanupStuff
public DoStuff()
{
} // eo ctor
public void DoMethod()
{
var x = DoSetupStuff();
DoStuffImpl(x);
DoCleanupStuff(x);
} // eo DoMethod
} // eo class DoStuff
Then provide specializations:
public class Special1 : DoStuff
{
protected override DoStuffImpl(var x)
{
// work with x here
}
} // eo class Special1
public class Special2 : DoStuff
{
protected override DoStuffImpl(var x)
{
// work with x here, but in a different way
}
} // eo class Special2
// work with them
Special1 s1; s1.DoMethod();
Special2 s2; s2.DoMethod();
I'd use a method such as this:
void ExecuteMethodWithSetupAndCleanup(Action<int> method)
{
// do the setup stuff
var x = DoSetupStuff();
// run the provided code
method(x);
// do the cleanup stuff
DoCleanupStuff(x);
}
And then use it like this:
void method1()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method1 specific code using x
}
}
void method2()
{
ExecuteMethodWithSetupAndCleanup(x =>
{
// here is the method2 specific code using x
}
}
Alternatively, if you already have method1() and method2() and you want to keep them separate, and only remove the setup/cleanup from them, you can do something like this:
void method1(int x)
{
// here is the method1 specific code using x
}
void method2(int x)
{
// here is the method2 specific code using x
}
void ExecuteMethod1AndMethod2()
{
ExecuteMethodWithSetupAndCleanup(method1);
ExecuteMethodWithSetupAndCleanup(method2);
}
How about something like:
protected Action DoSetupStuff()
{
//... setup code
Action cleanup = () =>
{
//... prepare cleanup code for later
};
return cleanup;
}
void DoSomethingUseful()
{
var cleanup = DoSetupStuff();
// do something useful
cleanup();
}
This way, your setup method prepares its own cleanup code, and your primary DoSomethingUseful method never has to know about it.
Related
Let's say I have written a unit test to test a public method in XUnit.
[Fact]
public void MethodA_WhenSomething_ThenReturnNull()
{
// Code removed for brevity.
// Assert
}
This is MethodA.
public void MethodA() {
MethodOne();
MethodTwo();
MethodThree();
}
MethodOne, MethodTwo and MethodTree are all private method. Is there a way to skip a private method (ie MethodTwo) while running my unit test for MethodA? The reason I want to skip methodTwo is because methodTwo calling a stored procedure and it causes error in Xunit. But I know the stored procedure is running fine without issue, so it is okay for me to skip this method.
And the moment, I am using this way.
public void MethodA() {
MethodOne();
#if DEBUG == false
MethodTwo();
#endif
MethodThree();
}
If there is a better way, I wish not to put If DEBUG
This kind of problem is typically solved via Moq.Protected.
So, you need to change private accessor to protected at least for MethodTwo.
But I would suggest to change all accessors to protected.
public class SomeClass
{
public void MethodA()
{
MethodOne();
MethodTwo();
MethodThree();
}
protected void MethodOne() { ... }
protected void MethodTwo() { ... }
protected void MethodThree() { ... }
}
With this, the mock setup would look like this:
using Moq.Protected;
...
var mockSomeClass = new Mock<SomeClass>();
mockSomeClass.Protected()
.Setup("MethodTwo")
.Verifiable();
Additionally you can setup a Callback to write something out the test output
const string toBeMockedMethodName = "MethodTwo";
mockSomeClass.Protected()
.Setup(toBeMockedMethodName)
.Callback(() => TestContext.Progress.Writeline($"{toBeMockedMethodName} has been called."))
.Verifiable();
References:
Mocking protected members
Protected Members - Unit testing in C#
Moq - how to mock a protected method of an internal class with no parameter-less constructor
If your private method depends on some external service, then you can create make a mock of it and mark it verifiable.
[Fact]
public void MethodA_WhenSomething_ThenReturnNull()
{
var barService = new Mock<Bar>();
barService.Setup(x => x.DoSomething()).Verifiable();
///
}
public class Foo
{
public void MethodA()
{
MethodOne();
MethodTwo();
MethodThree();
}
private void MethodThree() => System.Console.WriteLine();
private void MethodTwo() => new Bar().DoSomething();
private void MethodOne() => System.Console.WriteLine();
}
public class Bar
{
public void DoSomething() => System.Console.WriteLine("....");
}
There are several ways that you can use to replace the private method. Let's use the MethodRedirect library.
Let's say there is the following class:
public class SomeClass
{
public void MethodA()
{
MethodOne();
MethodTwo();
MethodThree();
}
private void MethodOne() { }
private void MethodTwo() =>
throw new NotImplementedException();
private void MethodThree() { }
}
var sc = new SomeClass();
sc.MethodA(); // An exception will be thrown here.
The above library does not have a nuget package. Therefore, we simply copy three files from sources: Extensions.cs, MethodOperation.cs, MethodToken.cs.
Then write the following unit test:
[Fact]
public void MethodA_WhenCalled_NotThrow()
{
var sut = new SomeClass();
var fake = new Fake();
MethodInfo privateMethod = sut.GetType().GetMethod("MethodTwo", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo redirectMethod = fake.GetType().GetMethod("Redirect", BindingFlags.Static | BindingFlags.NonPublic);
var token = privateMethod.RedirectTo(redirectMethod);
sut.MethodA(); // should not throw
token.Restore();
}
Auxiliary class whose method will be used as a replacement
public class Fake
{
static void Redirect() { }
}
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();
}
I have this code:
class SomeClass {
void someFunction()
{
Action<string> myAction = (what)=>
{
//whatever
}
new List<string>().ForEach(myAction);
}
}
I'd like to extract the code inside myAction into a separate member function.
How do I do that?
class SomeClass
{
void someFunction()
{
Action<string> myAction = Whatever;
new List<string>().ForEach(myAction);
}
public void Whatever(string what)
{
// ... whenever
}
}
or directly, without defining a local Action<string> variable (that will probably be optimized away in Release mode anyway):
new List<string>().ForEach(Whatever);
This should be equivalent:
class SomeClass {
void myAction(string what)
{
// whatever
}
void someFunction()
{
new List<string>().ForEach(item => myAction(item));
}
}
Since Action<string> means a method with a string parameter which does not return a value.
Are you looking for this?
class SomeClass {
void someFunction()
{
new List<string>().ForEach(SeparateMemberFunction);
}
void SeparateMemberFunction(string s)
{
//whatever
}
}
I use a different way:
class SomeClass
{
public void SomeFunction()
{
new List<string>().ForEach(e => this.MyAction(e));
}
private void MyAction(string str){ /* ... */ }
}
I find it clearer because I see at first sight MyActionis a method and not a field or a property
I need to get MethodInfo for method called in Action delegate in order to check, whether methods called in Action has MyCustomAttibute
public void Foo( Action action )
{
if(Attribute.GetCustomAttributes(action.Method, typeof(MyCustomAttribute)).Count() == 0)
{
throw new ArgumentException("Invalid action");
}
}
The Foo method should be able to be called as following:
Foo(() =>
{
instanceOfFooClass.Method1().Method2();
});
In Foo method I want to be sure that Method1 and Method2 has MyCustomAttribute. However action.Method is giving me the MethodInfo, which is the action of delegate, which happens when using lambda expression. Is there any way to get Method1 and Method2 MethodInfo?
As mentioned in the comments, Expression<T> is probably the best way to achieve this. However, it requires a Compile() at runtime so it should be performance profiled.
With Expression<T> you can easily get access to Method info like this:
public MethodInfo GetMethodInfo(Expression<Action> action)
{
return ((MethodCallExpression)action.Body).Method;
}
But, before executing the action you must do this:
private void InvokeMethod(Expression<Action> action)
{
action.Compile().Invoke();
}
EDIT
Ah yes, I forgot how to get access to the customer attribute. You would do it like this:
var methodInfo = ((MethodCallExpression)myAction.Body).Method;
var attributes = methodInfo.GetCustomAttributes<T>(true);
EXAMPLE
Here is an example showing passing chained method calls to Expression<Action>:
public class ActionTest
{
public void DoAction(Action action)
{
action();
}
public void DoExpressionAction(Expression<Action> action)
{
var method2Info = ((MethodCallExpression)action.Body).Method;
// a little recursion needed here
var method1Info = ((MethodCallExpression)((MethodCallExpression)action.Body).Object).Method;
var myattributes2 = method2Info.GetCustomAttributes(typeof(MyAttribute), true);
var myattributes1 = method1Info.GetCustomAttributes(typeof(MyAttribute), true);
action.Compile().Invoke();
}
}
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
private string message;
public MyAttribute(string message)
{
this.message = message;
}
}
public class MethodTest
{
[MyAttribute("Number1")]
public MethodTest Method1()
{
Console.WriteLine("Action");
return this;
}
[MyAttribute("Number2")]
public MethodTest Method2()
{
Console.WriteLine("ExpressionAction");
return this;
}
}
class Program
{
static void Main(string[] args)
{
ActionTest target = new ActionTest();
MethodTest instance = new MethodTest();
target.DoExpressionAction(() => instance.Method1().Method2() );
Console.ReadLine();
}
static void Method1()
{
Console.WriteLine("Action");
}
static void Method2()
{
Console.WriteLine("ExpressionAction");
}
}
If you call your Foo() methdod like this:
Foo(instanceOfFooClass.Method);
Your code works as you'd expect (void methods are actions, after all).
On a side note, I think "chaining" method calls in fact counts as you're only passing the last one through.
Full sample demonstrating the behavior:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication4
{
class MyCustomAttribute : Attribute { }
class FooClass
{
[MyCustom]
public void DecoratedMethod() { Console.WriteLine("Decorated Method - executed."); }
public void NotDecoratedMethod() { Console.WriteLine("Not Decoreated Method - executed."); }
}
class Program
{
static void Main(string[] args)
{
FooClass instanceOfFooClass = new FooClass();
Foo(instanceOfFooClass.DecoratedMethod);
Foo(instanceOfFooClass.NotDecoratedMethod);
Console.ReadLine();
}
public static void Foo(Action action)
{
if (Attribute.GetCustomAttributes(action.Method, typeof(MyCustomAttribute)).Count() == 0)
Console.WriteLine(string.Format("Invalid method {0}", action.Method.Name));
else
{
Console.WriteLine(string.Format("Valid method {0}", action.Method.Name));
action.Invoke();
}
}
}
}
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();
}