c#如何将类型不明确的对象(例如'var')作为特定类型的对象(例如'Form')访问

本文关键字:例如 对象 类型 Form 访问 不明确 var | 更新日期: 2023-09-27 18:01:48

我试图迭代表单列表(Mdichildren),并比较列表中特定表单的值。然而,使用var来包含任何类型的表单会使表单难以使用。

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)
    {
    }
}

并且cast形式仍将引用我要更改的列表中的项目。

我刚刚想过有一种方法可以使用form作为Form_OvenControl,并且基本上在一行中访问其中的变量

c#如何将类型不明确的对象(例如'var')作为特定类型的对象(例如'Form')访问

  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
    }
    

更新

在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,它在每个继承程序中都是overridden。虚方法的实现可以处理您所需要的任何内容。你可以传递任何你需要的参数

编辑:如果您必须实例化From,则使用virtual。对于抽象类,这是不可能的。
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的Open/Closed原则!


编辑:如果你不能修改表单类

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方法。

相关文章: