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