Replacing a class implementation in C #

Is it possible to replace (or override) the class definition with one of my own implementations?

Explanation:

  • I have a class with an instance of System.Random and I'm trying to run test without changing its source code ...
  • So, I plan to replace the Random class with one of my own implementations, which allows me to control the generated sequence. See this question .

`

class foo
{
    Random r=new Random();
    double bar()
    {
         double ans=r.NextDouble();
         .....// evaluate ans
         return ans;
    }
}

`

In what ways can I replace the implementation of the Random class with another without changing (or with minimal changes) the source code file?

:
Random ... Random ... , !!
2:
#: " Random - MyNamespace.Random not System.Random"??

+3
7

, .

, .

System.Random sealed, , .

, - , .

unit test :

class MyRandom : System.Random 
{
     public override double NextDouble()
     {     
          // return your fake random double here.
     }
}


class TestFixture 
{
     public void UnitTest()
     {
          // Create the unit under test
          foo unit = new foo();

          // use reflection to inject a mock instance
          typeof(foo)
             .GetField("r", BindingFlags.Instance | BindingFlags.NonPublic)
             .SetValue(unit, new MyRandom());

          // ACT: call method
          var result = foo.bar();

          // examine results
      }
 }
+3

EDIT: ChaosPandion, , .. double bar(double input) { ... }, , , :

bar, Func<double> :

double bar(Func<double> source)
{
    double ans = source();
    //evaluate ans
    return ans;
}

, :

Random r = new Random();
double ans = bar(r.NextDouble);

IRandom, Random mocks :

interface IRandom
{
    double Next();
}

public class RandomWrapper : IRandom
{
    private Random r = new Random();
    public double Next()
    {
        return this.r.NextDouble();
    }
}
+5

, Random , JustMock TypeMock.

, ( ), , , #. , , , , , , .

+2

System.Random .

class PseudoRandom : System.Random
{
    public override int Next () {...}
    public override int Next (int maxValue) {...}
    public override int Next (int minValue, int maxValue) {...}
    public override void NextBytes (byte [] buffer) {...}
    public override double NextDouble () {...}
}

Main.

Random random = new PseudoRandom ();

, , "is". (, , )

// We need to see which class we're working with
if (random is PseudoRandom)
{
    // Using our custom class
}
else
{
    // Using default System.Random class
}
+1

Injection Dependency. . DI/IoC #.

Ninject , .

0

.

, , Random.

, Random, - "" .

Ensure proper implementation when and where it is needed.

0
source

Answer A is a bit confusing, but it works

public class Foo 
{
   Func<double> next;
   Foo(bool use_new) 
   {
       if(use_new)
          next = (new MyRandom()).NextDouble;
       else
          next = (new Random()).NextDouble;            
   }
   void bar() 
   {
       ans = next();
       ...
   }
}

Answer B , a little understood by imho intent. Define a common interface that returns a function. Then just select which function to use.

public interface IRandomProvider
{
    Func<double> NextDouble { get; }
}

public class StdRandomProvider : IRandomProvider
{
    Random r = new Random();
    Func<double> NextDouble
    {
        get { return ()=>r.NextDouble(); }
    }
}

public class MyRandomProvider : IRandomProvider
{
    MyRandom r = new MyRandom();
    Func<double> NextDouble
    {
        get { return ()=>r.MyNextDouble(); }
    }
}

public class Foo 
{
   IRandomProvider r;
   Foo(bool use_new) 
   {
       if(use_new)
          r= new MyRandomProvider();
       else
          r= new StdRandomProvider();            
   }
   void bar() 
   {
       ans = r.NextDouble();
       ...
   }
}
0
source

Source: https://habr.com/ru/post/1775732/


All Articles