C# - How to pass and run a method in a function? - c#

I'm trying to write a wrapper for a Selenium test that re-runs the test if it fails, I've got the mechanics working fine. But I need to figure out a way of passing either a function/method or (preferably) multiple methods inside of the function. Here's an example of what I want to achieve:
In the wrapper class:
public class TestRunner{
public void RunTest(function FuncToRun){
FuncToRun();
}
}
In the test:
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(Test());
}
This is purely for demonstration. I know that this doesn't work, but I hope it will convey my point to you.

Looks as though you need a delegate.
An applicable delegate for your scenario is the Action delegate which can be used to represent a single parameterless method.
public class TestRunner
{
public void RunTests(params Action[] tests)
{
foreach (var test in tests)
{
test.Invoke();
}
}
}
Note the use of the params keyword which will allow you ro supply any number of tests to the RunTests method. Here is an example using an implicit method group conversion:
public class Tests
{
public void TestOne() {
}
public void TestTwo() {
}
}
...
var runner = new TestRunner();
var tests = new Tests();
runner.RunTests(tests.TestOne, tests.TestTwo);

You could use Action parameters to do this
public class TestRunner{
public void RunTest(Action FuncToRun){
FuncToRun();
}
}
public class Tests{
public void Test(){
...Run test methods...
}
TestRunner.RunTest(() => Test());
}

You want to do something like this. But need more context as in inputs and what return value you are expecting.
Func<string, int> myMethodName
This is an example of usage:
public bool RunThisMethod(Func<string, int> myMethod)
{
//... do stuff
int i = myMethod("My String");
//... do more stuff
return true;
}

use delegate . simply declare a delegate to the method you want to pass and call and assign the method to it.
http://msdn.microsoft.com/en-IN/library/ms173171.aspx

You may use delegates or even Action or Func objects.
public class TestRunner{
public void RunTest(Action funcAction){
funcAction();
}
}
public class Tests{
public void Test(){}
TestRunner.RunTest(Test);
}

Related

Decorating a static class C#

I've got a design question.
I've got a static class used in some old code that calls a static method to run some operation. If a certain condition is met, I want to call another method right after it.
I wanted to use the decorator pattern but I can't exactly return an instance of the static class if the condition is not met.
This is what's happening now.
var result = StaticClass.DoSomething(some parameters);
What I want is to write to a database right after that DoSomething is called if another variable is true and I didn't want to just pile on to the old code with conditionals so I'd rather delegate that to some other class. This is what I really want to do.
var result = StaticClassFactory(condition).DoSomething(some parameters);
Class1
void DoSomething(parameters) {
StaticClass.DoSomething()
}
Class2
void DoSomething(parameters) {
StaticClass.DoSomething();
DoSomethignElse();
}
Any suggestions?
What you can do is use an interface to represent the "doer":
public interface IDoer
{
void DoSomething(object parameters);
}
Then create the two classes:
public class DefaultDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
}
}
public class AugmentedDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
DoSomethingElse();
}
}
Then use a factory to return an instance that implements IDoer based on the condition:
public class DoerFactory
{
public IDoer GetDoer(object someCondition)
{
//Determine which instance to create and return it here
}
}
I used placeholders of type object for some things as no more information is available.

Method call that call method from other object

I was wondering if it's possible to otain such behaviour where method call of one object will call method of another object.
public class Example
{
public void DoSomething() { /*BASICALLY NOTHING*/ }
}
public class Engine
{
public void DoSomething() { Console.WriteLine("bleee"); }
static void Main()
{
Example e = new Example();
Engine eng = new Engine();
e.DoSomething = eng.DoSomething;
}
}
My Example object is exactly dummy object, but I would like to use this class as base class and build on top of it something more fancy.
So e.DoSomething() should call method from eng.DoSomething(). I can't use inheritance or pass Engine object to Example as argument.
Is it possible? How to achieve that? Is such approach used somewhere?
You can't do this in the way you describe, but you can do it with delegates.
public class Example
{
public Action DoSomething {get; set;}
}
public class Engine
{
public void DoSomething() { Console.WriteLine("bleee"); }
static void Main()
{
Example e = new Example();
Engine eng = new Engine();
e.DoSomething = eng.DoSomething;
}
}
Now you can say e.DoSomething() and it will call via the delegate by calling the getter and then calling the returned action.
Using reflection we can do the method call with same type info. But other types method is not possible. I think so.

Alternatives inline interface implementation in C#

I'd like to use inline interface implementation in C# but reading some posts like this or this I found out that it's not like Java do it.
Supposing this interface:
public interface MyListener {
void onHandleOne();
void onHandleTwo();
}
and I pass this interface as a parameter:
myMethod(MyListener listener){
//some logic
}
and when I call it I'd like to do inline imlementation like in java:
myMethod(new MyListener () {
#Override
public void onHandleOne() {
//do work
}
#Override
public void onHandleTwo() {
//do work
}
});
As an alternative I made a class that implements yhis interface and use this class to call my method:
public class MyImplementor : MyListener {
public void onHandleOne() {
//do work
}
public void onHandleTwo() {
//do work
}
}
and call my method: myMethod(new MyImplementor())
but this solutions needs a new class every time I'll call this method (for different behavior) maybe is there a way using lambda or somehow to do it like:
myMethod(new MyImplementor() =>{//handle my methods})
but this solutions needs a new class every time I'll call this method
(for different behavior) maybe is there a way using lambda or somehow
to do it like
Yes, give it a delegate parameter and pass it a lambda.
public class MyImplementor : MyListener
{
private readonly Action handle1;
private readonly Action handle2;
public MyImplementor(Action handle1, Action handle2)
{
this.handle1 = handle1;
this.handle2 = handle2;
}
public void onHandleOne()
{
handle1();
}
public void onHandleTwo()
{
handle2();
}
}
Then you can use it as
myMethod(new MyImplementor(()=>{//handle method1}, ()=>{//Handle method2});

How can I change the behavior of a static method at runtime?

Is there a way to modify the behavior of a static method at runtime?
for example:
Say I have this class
public class Utility {
public static void DoSomething(string data){
//...
}
}
Is there a way to do something like this:
typeof(Utility).SetMethod("DoSomething", (data) => { /*Do something else...*/ });
Such that if you call Utility.DoSomething it executes the new code?
What you want to do is pass the behavior you want as another parameter into the function.
public static void DoSomething(string data, Action<string> operation)
{
operation(data);
}
This is an oversimplified example, of course. What you actually wind up doing in your own code is going to depend on what operation actually does.
If you're trying to modify the behavior of an existing, compiled, in-production method, and cannot overload or override the method in the usual ways, the only way I know of to do that is CIL Rewriting, possibly using an Aspect Weaver.
Sure.
public class Utility {
public static Action<String> _DoSomething;
public static void DoSomething(string data){
if (_DoSomething != null) {
_DoSomething();
return;
}
// default behavior here.
}
}
And to mask the default behavior:
Utility._DoSomething = (data) => { /* do something else */ };
I don't see why you wouldn't just create a new class that inherits from Utility and define a new function that does what you want.
public class Program
{
static void Main(string[] args)
{
if (true)
{
Utility.DoSomething("TEST");
} else
{
Util1.DoSomething("TEST");
}
}
}
public class Utility
{
public static void DoSomething(string data)
{
//Perform some action
}
}
abstract class Util1 : Utility
{
public static new void DoSomething(string data)
{
//Perform a different action
}
}
I think although it is possible to do this you should ask yourself: "Why do I need this functionality"? Usually a method stays as is, and does what it is supposed to do according to its interface which is given by its name and signature. So while you can add additional logic by adding an Action<T>-parameter to your signature you should ask yourself if this won´t break the contract of the interface and therefor what the method was designed for.
Having said this you should consider either overwrite your method if the functionality you need is some kind of "making the same things differently then the parent-class" or extend it by adding a dependency into your consuming class and add some methods to that class that extent the functionality provided by the contained class (see also favour composition over inheritance)
class MyClass {
Utility MyUtility;
void ExtraMethod() { /* ... */ }
}
EDIT: As you´re using a static method the opportunity on overwriting is obsolete. However IMO that sounds like a great design-flaw.

c# - Assert Expressions

I have an 'Example' class and I would like to create unit test for it. Take a look on my classes below:
public class Example
{
private readonly Calculator _calculator;
public Example(ICalculator calculator)
{
_calculator = calculator;
}
public void Calculate()
{
_calculator.Execute(operation => operation.Subtract());
}
}
public interface IOperation {
void Sum();
void Subtract();
}
public inferface ICalculator {
void Execute(Action<IOperation> action);
}
public class Calculator {
public void Execute(Action<IOperation> action){}
}
What I want is to create a Unit Test class to verify that my method from Example class Calculate calls the _calculator.Execute passing as parameter the operation.Subtract(). Is it possible?
I know how to mock my ICalculator and verify that Execute is being called once, but I have no idea how to validade if Execute method was called using operation.Subtract() as parameter instead of operation.Sum().
I am using NUnit to create my unit tests. Here you can see how my unit test class is at the moment:
[TestFixture]
public class ExampleTests
{
[Test]
public void Test1()
{
var calculator = new Mock<ICalculator>();
var subject = new Example(calculator.Object);
subject.Calculate();
calculator.Verify(x => x.Execute(It.IsAny<Action<IOperation>>()), Times.Once);
}
}
Hope someone can understand my english, sorry about that.
You cannot directly verify what lambda was passed but you can go around it by actually invoking said lambda with yet another mock:
var calculator = new Mock<ICalculator>();
var operation = new Mock<IOperation>();
// when calculator's Execute is called, invoke it's argument (Action<IOperation>)
// with mocked IOperation which will later be verified
calculator
.Setup(c => c.Execute(It.IsAny<Action<IOperation>>()))
.Callback<Action<IOperation>>(args => args(operation.Object));
var example = new Example(calculator.Object);
example.Calculate();
calculator.Verify(c => c.Execute(It.IsAny<Action<IOperation>>()));
operation.Verify(o => o.Subtract());
You're passing anonymous delegate operation => operation.Subtract() to _calculator.Execute - so you cannot construct it later when asserting for argument.
You can get around it by doing this:
public class Example
{
private readonly ICalculator _calculator;
public Example(ICalculator calculator)
{
_calculator = calculator;
}
public Action<IOperation> Subtract = op => op.Subtract();
public Action<IOperation> Add = op => op.Sum();
public void Calculate()
{
_calculator.Execute(Subtract);
}
}
And asserting like this (ommiting 2nd param defaults to Once):
calculator.Verify(x => x.Execute(subject.Subtract));
However this looks like convoluted design in order to be able to write a test.

Categories

Resources