繁体   English   中英

C#如何将模糊输入的对象(例如“ var”)作为特定类型的对象(例如“ Form”)访问

[英]C# How to access an ambiguously typed object (e.g. 'var') as a specifically typed object (e.g. 'Form')

我正在尝试迭代表单列表(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并基本上在一行中访问其中的变量。

  1. 它不是“模糊类型的对象”。 那有什么意思? 你从哪儿弄来的?

    这是一个强类型变量,其类型由编译器的推论确定。 在这种情况下可能是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) { } 
  2. 我知道我可以转换值并创建这种形式的新变量,但是我想通过列表中的引用使用对象

    只需将其转换为所需的类型即可:

     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 } 

UPDATE

在C#7中...

    if (form is Form_OvenControl ovenform)
    {
        if (oven.Id == ovenform.ovenId)
        {
        }
    }
    else if (form is Form_Instructions instform)
    {
        // do something with instform
    }

您可以在Form类上定义一个virtual method ,该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");
    }
}

每当添加新的Form类型时,只需实现DoJob方法,并且代码无需修改即可工作。

这也符合SOLID的打开/关闭原则!


编辑:如果您不能在窗体类上进行修改

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");
    }
}

定义一个继承自Form类的FormMiddleMan类。 它定义了DoJob方法。 您的每个具体类型都继承自FormMiddleMan ,并且必须实现DoJob方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM