我正在尝试迭代表单列表(Mdichildren),并比较列表中特定表单的值。但是,使用var来包含任何类型的Form会使得很难使用form.Value可能特定于给定的表单。
foreach (var oven in Ovens) // list of objects
{
foreach (var form in this.Mdichildren) // contains multiple form types
{
if (form is Form_OvenControl)
{
if (oven.Id == form.ovenId)
{
// this fails because form.ovenId is treated like var, not like Form_OvenControl
}
}
else if (form is Form_Instructions)
{
// do something with different type of form
}
}
}
我知道我可以转换值并为该类型的表单创建一个新变量,但我希望在列表中通过引用使用该对象。我敢肯定我可以找到一种愚蠢的方式,但我确信有一种巧妙的方法可以做某事(不那么违法,但是)像:
(Form_OvenControl)form.formSpecificValue = 0;
修改: 正如下面明确指出的那样,我可以简单地做到以下几点:
if (form is Form_OvenControl)
{
var ovenform = form as Form_OvenControl;
if (oven.Id == ovenform.ovenId)
{
}
}
并且演员表格仍然会引用我想要改变的列表中的项目。
我原本以为有一种方法可以使用Form作为Form_OvenControl,并且基本上在一行中访问其中的变量。
答案 0 :(得分:3)
它不是"模糊类型的对象"。那有什么意思?你从哪里得到的?
它是一个强类型变量,其类型由编译器推断确定。在这种情况下可能Form
。
在编译器可以从上下文推断出类型的情况下,这只是保存输入和视觉混乱的简写:
// l is of type List<int> b/c duh
var l = new List<int>();
// n must be int, because l is List<int>
foreach (var n in l)
{
}
该代码与此代码完全相同:
List<int> l = new List<int>();
foreach (int n in l)
{
}
我知道我可以转换值并为该类型的表单创建一个新变量,但我希望在列表中通过引用使用该对象
只需将其转换为所需的类型:
if (form is Form_OvenControl)
{
var ovenform = form as Form_OvenControl;
if (oven.Id == ovenform.ovenId)
{
}
}
else if (form is Form_Instructions)
{
var instform = form as Form_Instructions;
// do something with different type of form
}
在C#7 ......
if (form is Form_OvenControl ovenform)
{
if (oven.Id == ovenform.ovenId)
{
}
}
else if (form is Form_Instructions instform)
{
// do something with instform
}
答案 1 :(得分:1)
您可以在类Form上定义virtual method
,在每个继承者中overridden
。虚拟方法的实现可以处理您需要的任何内容。你可以传递你需要的任何参数。
编辑:使用虚拟,以防您必须实例化From
。对于抽象类,这是不可能的。
class Program {
static void Main(string[] args) {
Form big = new FormBig();
Form small = new FormSmall();
big.DoJob(null); // FormBig
small.DoJob(null); // FormSmall
Console.ReadLine();
}
}
class Form {
public virtual void DoJob(object parametersYouNeed) {
throw new NotImplementedException("use only on inheritor");
}
}
class FormBig : Form {
public override void DoJob(object parametersYouNeed) {
Console.WriteLine("FormBig");
}
}
class FormSmall : Form {
public override void DoJob(object parametersYouNeed) {
Console.WriteLine("FormSmall");
}
}
每当您添加新的表单类型时,您只需要实现方法DoJob
,并且您的代码无需修改即可正常运行。
这也符合S.O.L.I.D的开放/封闭原则!
class Program {
static void Main(string[] args) {
FormMiddleMan big = new FormBig();
FormMiddleMan small = new FormSmall();
big.DoJob(null); // FormBig
small.DoJob(null); // FormSmall
Console.ReadLine();
}
}
class Form {
}
abstract class FormMiddleMan : Form {
public abstract void DoJob(object parametersYouNeed);
}
class FormBig : FormMiddleMan {
public override void DoJob(object parametersYouNeed) {
Console.WriteLine("FormBig");
}
}
class FormSmall : FormMiddleMan {
public override void DoJob(object parametersYouNeed) {
Console.WriteLine("FormSmall");
}
}
定义一个继承自FormMiddleMan
类的Form
类。它定义了DoJob
方法。每个具体类型都继承自FormMiddleMan
,并且必须实现DoJob
方法。