Roald
Roald

Reputation: 3009

Change the class of an already initialized variable

For testing purposes I want to be able to change which class is bound to the variable sensor. Normally the program would use data measured by a sensor through the Sensor class. However, if no sensor is connected, I can simulate its behavior using the SensorSimulator class.

What I currently do is comment out the class which I do not want to use. How can I make it work such that with the click of a button in the GUI I can switch between the Sensor and SensorSimulator classes? Or is there alternative way to do this?

Code

using System.Windows.Forms;

namespace SO_question
{
    public partial class Form1 : Form
    {
        //private Sensor sensor;
        private SensorSimulator sensor;

        public Form1()
        {
            InitializeComponent();

            //sensor = new Sensor();
            sensor = new SensorSimulator();

            var data = sensor.getData();
            sensor.stopMeasuing();
        }
    }

    class Sensor
    {
        public virtual int getData()
        {
            return 0;
        }

        public void stopMeasuing() { }
    }

    class SensorSimulator : Sensor
    {
        public override int getData()
        {
            return 1;
        }
    }
}

Upvotes: 0

Views: 64

Answers (3)

Rufus L
Rufus L

Reputation: 37060

Although creating a common interface is usually preferable, you don't have to do anything to your existing code, you can just switch the type at runtime, as long as you declare sensor as the base class type Sensor and don't expect to use any SensorSimulator-specific methods:

private Sensor sensor;

private void Form1_Load(object sender, EventArgs e)
{
    sensor = new Sensor();           
    var data = sensor.getData();
    sensor.stopMeasuing();
}    

private void button1_Click(object sender, EventArgs e)
{
    // Detect the type of `sensor` and switch it
    if (sensor is SensorSimulator) sensor = new Sensor();
    else sensor = new SensorSimulator();
}

Upvotes: 2

Divisadero
Divisadero

Reputation: 913

Create interface ISensor and let both Sensor and SensorSimulator implement it. Thats it.

EXTENDEND ANSWER:

public interface ISensor
{
    SensorData GetData();
}

public class SensorData
{
}

public class Sensor : ISensor
{
    public SensorData GetData()
    {

        return new SensorData();
    }
}

public class SensorSimulator : ISensor
{
    public SensorData GetData()
    {
        return new SensorData();
    }
}

public class SensorHost
{
    public ISensor Sensor { get; set; }

    public void Measure()
    {
        Console.WriteLine(Sensor.GetData());
    }
}

public static class Program
{
    static void Main(string[] args)
    {
        SensorHost host = new SensorHost();
        host.Sensor = new Sensor();
        // measures by real sensor
        host.Measure();

        host.Sensor = new SensorSimulator();
        // measures by sensor simulator
        host.Measure();

    }
}

Here you can see the idea. Program will create SensorHost ~ the code you have in Form1. This host keeps the property Sensor of type ISensor. So you can set it to the whatever that implements this interface. First call of Measure() will use the real Sensor. The second call will be called on SensorSimulator. It is called polymorphism.

Upvotes: 3

Ken Tucker
Ken Tucker

Reputation: 4156

Use an interface to define the classes.

public interface ISensor
{

    int GetData();

    void StopProcessing();
}


public class Sensor : ISensor
{
    public int GetData()
    {
        return 0;
    }

    public void StopProcessing()
    {
        //throw new NotImplementedException();
    }
}

public class SensorSimulator : ISensor
{
    public int GetData()
    {
        return 1;
    }

    public void StopProcessing()
    {
        //throw new NotImplementedException();
    }
}

Then you can do this

        ISensor sensor;
        sensor = new Sensor();

        sensor = new SensorSimulator();

Upvotes: 1

Related Questions