Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态设置对方法中使用的变量的引用_C#_Dictionary_Methods_Structure - Fatal编程技术网

C# 动态设置对方法中使用的变量的引用

C# 动态设置对方法中使用的变量的引用,c#,dictionary,methods,structure,C#,Dictionary,Methods,Structure,我不确定这个标题是否正确。无论如何,我有一个类,它有许多控制立体声的方法。每个方法将向串行端口发送一个命令。支持多种型号的立体声系统,每个立体声系统可能需要发送不同的命令。 例如,型号A可能需要将命令“VOLUP”发送到串行端口,“型号B”可能需要发送命令“GAINUP”以增加音量。我想要一个名为IncreaseVolume的方法,如下所示: public void IncreaseVolume() { serialPort.WriteLine(volumeCommand); }

我不确定这个标题是否正确。无论如何,我有一个类,它有许多控制立体声的方法。每个方法将向串行端口发送一个命令。支持多种型号的立体声系统,每个立体声系统可能需要发送不同的命令。 例如,型号A可能需要将命令“VOLUP”发送到串行端口,“型号B”可能需要发送命令“GAINUP”以增加音量。我想要一个名为IncreaseVolume的方法,如下所示:

 public void IncreaseVolume()
 {
     serialPort.WriteLine(volumeCommand);
 }
设置收音机的型号后,将从另一个类调用此方法。现在,对于两台收音机,我可以做到:

public class StereoControl
{
    string volumeCommand;
    string model_A_Volume_Command = "VOLUP";
    string model_B_VOlume_Command = "GAINUP";

    public void Set_Radio_Model(string model)
    {
        if (model == "modelA")
        {
            volumeCommand = model_A_Volume_Command;
        }

        else if (model == "modelB")
        {
            volumeCommand = model_B_Volume_Command;
        }
     }

     public void IncreaseVolume(volumeCommand)
     {
         serialPort.WriteLine(volumeCommand);
     }
}
因此,主程序将首先设置模型,然后在需要增加音量的任何时候,都将调用IncreaseVolume方法。 问题是,可能有几十个立体声和几十个命令,我不一定希望所有这些都出现在if-then或case语句中。 我考虑过为每个包含命令的模型创建结构,但是如何选择在方法中使用的结构呢? 我相信有一种更优雅的方式可以做到这一点,我愿意接受建议

第一个答案虽然可用,但当我们得到100多个命令和200多个立体声时,它将有点太难处理。所以这里有另一种可能性,但我不知道如何在整个应用程序中获得可用的类引用

public Class Model_A
{
    string volumeCommand = "VOLUP";
}

public Class Model_B
{
    string volumeCommand = "GAINUP";
}

public Class StereoControl
{
    public void Set_Radio_Model(String model)
    {
        if (model == "model_a")
        {
             var _radio = new Model_A();
        }

         else if (model == "model_b")
        {
             var _radio = new Model_B();
        }
    }

    public void IncreaseVolume()
    {
        serialPort.WriteLine(_radio.volumeCommand);
    }
}
当然,这里的问题是,无线电的范围仅限于Set无线电模型。有没有办法让收音机到处都能用?
Tom

最基本的方法是拥有立体声名称的枚举,然后在OOP中实现它 (我希望人们帮助改进)这取决于我的意见

1-定义
enum
如下:

public enum StereoBrand
{
    Stero1 = 0,
    Stereo2 = 1
}
public interface IStereo
{
    string VolumeCommand { get; }
    string SteroeName { get; }
    void IncreaseVolume();
}
public class Stereo1 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo1";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command1";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand
    }
    public Stereo1()
    {

    }
}
public class Stereo2 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo2";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command2";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand2
    }
    public Stereo2()
    {

    }
}
2-定义一个接口以强制所有立体声执行
IncreaseVolume()
类似:

public enum StereoBrand
{
    Stero1 = 0,
    Stereo2 = 1
}
public interface IStereo
{
    string VolumeCommand { get; }
    string SteroeName { get; }
    void IncreaseVolume();
}
public class Stereo1 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo1";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command1";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand
    }
    public Stereo1()
    {

    }
}
public class Stereo2 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo2";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command2";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand2
    }
    public Stereo2()
    {

    }
}
通过上面的界面,每个立体声都应该有一个名为
StereoName

3-然后执行StereoController,如:

public class SteroController : IStereo
{
    public virtual string SteroeName
    {
        get
        {
            return string.Empty;
        }
    }

    public virtual string VolumeCommand
    {
        get
        {
            return string.Empty;
        }
    }
    public virtual void IncreaseVolume()
    {
        throw new NotImplementedException();
    }
    public static SteroController GenerateStereo(StereoBrand brand)
    {
        SteroController stereo = null;
        switch (brand)
        {
            case StereoBrand.Stero1:
                stereo = new Stereo1();
                break;
            case StereoBrand.Stereo2:
                stereo = new Stereo2();
                break;
        }
        return stereo;
    } 
}
步骤3的注释:

3.1-
StereoController
执行
IStereo
并将该道具和增加方法更改为虚拟,以便所有立体声设备都可以覆盖它们

3.2-
GenerateStereo
通过其
StereoName

4-假设我们必须在这里实现立体声类
Stereo1
Stereo2
如下:

public enum StereoBrand
{
    Stero1 = 0,
    Stereo2 = 1
}
public interface IStereo
{
    string VolumeCommand { get; }
    string SteroeName { get; }
    void IncreaseVolume();
}
public class Stereo1 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo1";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command1";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand
    }
    public Stereo1()
    {

    }
}
public class Stereo2 : SteroController
{
    public override string SteroeName
    {
        get
        {
            return "Streo2";
        }
    }

    public override string VolumeCommand
    {
        get
        {
            return "Command2";
        }
    }

    public override void IncreaseVolume()
    {
        //Do anything with VolumCommand2
    }
    public Stereo2()
    {

    }
}
5-最后一步是使用它们,如:

var stero = SteroController.GenerateStereo((StereoBrand)Enum.Parse(typeof(StereoBrand), "brandName"));
stero.IncreaseVolume();
注:

N1:最好通过反射实现
generateSeteo
,这意味着找到所有
IStereo
,并通过反射生成一个实例

N2:避免开关盒的另一个解决方案是使用反射来查找相关的立体声,如:

public static SteroController GenerateStereo(StereoBrand brand)
{
    SteroController stereo = null;
    var type = typeof(IStereo);
    var types = AppDomain.CurrentDomain.GetAssemblies()//Find all classes which implemented ISereo
        .SelectMany(s => s.GetTypes())
        .Where(p => type.IsAssignableFrom(p)).ToList();
    foreach(Type t in types)
    {
        var stereoNameProp = t.GetProperties().SingleOrDefault(p => p.Name == "StereoName");//Get stereo name prop
        if (stereoNameProp != null && stereoNameProp.GetValue(t).ToString() == brand.ToString())//Check it with brand name
            stereo =(SteroController)Activator.CreateInstance(type);//Make an instance
    }  
    return stereo;
}

希望对您有所帮助,并为您提供线索。

基本面向对象设计会说,为每个模型创建类,这些模型继承自父模型并处理其中的内容。不需要开关箱。@Tom,你看到我的答案了吗…,有什么意见吗?嗨,是的,我一直在研究它。有用的信息。另一条评论似乎提供了一个更简单的解决方案。为每个立体声创建一个类,然后在StereoController中使用它。回想起来,随着命令数量的增加(100+)和立体声数量增加到200,它似乎会变得非常繁忙。请看我的答案