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.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
}
}
}
我知道我可以强制转换该值并创建该类型表单的新变量,但我想在列表中通过引用使用该对象。我确定我可以想出一个 hacky 的方法,但我确定有一个巧妙的方法来做某事(不那么违法,但是)比如:
(Form_OvenControl)form.formSpecificValue = 0;
编辑:
正如下面亲切指出的那样,我可以简单地执行以下操作:
if (form is Form_OvenControl)
{
var ovenform = form as Form_OvenControl;
if (oven.Id == ovenform.ovenId)
{
}
}
而且转换形式仍会引用我要更改的列表中的项目。
我只是想有一种方法可以将表单用作 Form_OvenControl 并基本上在一行中访问其中的变量。
这不是 "ambiguously typed object"。那有什么意思?你从哪里弄来的?
它是一个强类型变量,其类型由编译器推断确定。在这种情况下可能是 Form
。
这只是 shorthand 在编译器可以从上下文推断类型的情况下避免打字和视觉混乱:
// 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)
{
}
I know I could cast the value and make a new variable of that type of form, but I want to use the object by reference in the list
只需将其转换为需要的类型即可:
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
}
您可以在 class 表单上定义一个 virtual method
,在每个继承者中都是 overridden
。虚方法的实现可以处理你需要的任何东西。你可以传递任何你需要的参数。
编辑:如果必须实例化,请使用虚拟 From
。这对于抽象 class.
是不可能的
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
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
class的FormMiddleMan
class。它定义了 DoJob
方法。您的每个具体类型都继承自 FormMiddleMan
并且必须实现 DoJob
方法。
我正在尝试迭代表单列表 (Mdichildren),并比较列表中特定表单的值。但是,使用 var 来包含任何类型的表单使得难以使用可能特定于给定表单的 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
}
}
}
我知道我可以强制转换该值并创建该类型表单的新变量,但我想在列表中通过引用使用该对象。我确定我可以想出一个 hacky 的方法,但我确定有一个巧妙的方法来做某事(不那么违法,但是)比如:
(Form_OvenControl)form.formSpecificValue = 0;
编辑: 正如下面亲切指出的那样,我可以简单地执行以下操作:
if (form is Form_OvenControl)
{
var ovenform = form as Form_OvenControl;
if (oven.Id == ovenform.ovenId)
{
}
}
而且转换形式仍会引用我要更改的列表中的项目。
我只是想有一种方法可以将表单用作 Form_OvenControl 并基本上在一行中访问其中的变量。
这不是 "ambiguously typed object"。那有什么意思?你从哪里弄来的?
它是一个强类型变量,其类型由编译器推断确定。在这种情况下可能是
Form
。这只是 shorthand 在编译器可以从上下文推断类型的情况下避免打字和视觉混乱:
// 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) { }
I know I could cast the value and make a new variable of that type of form, but I want to use the object by reference in the list
只需将其转换为需要的类型即可:
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
}
您可以在 class 表单上定义一个 virtual method
,在每个继承者中都是 overridden
。虚方法的实现可以处理你需要的任何东西。你可以传递任何你需要的参数。
编辑:如果必须实例化,请使用虚拟 From
。这对于抽象 class.
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
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
class的FormMiddleMan
class。它定义了 DoJob
方法。您的每个具体类型都继承自 FormMiddleMan
并且必须实现 DoJob
方法。