C# Windows窗体c的扩展类#
我有一个包含两个数组的类:RadioButton[]和Checkbox[]。我一次只需要看到其中一个。因为我需要做很多次,所以我想让一个扩展方法可见以优雅地完成这项工作C# Windows窗体c的扩展类#,c#,winforms,extension-methods,C#,Winforms,Extension Methods,我有一个包含两个数组的类:RadioButton[]和Checkbox[]。我一次只需要看到其中一个。因为我需要做很多次,所以我想让一个扩展方法可见以优雅地完成这项工作 public class AnswerForm { public RadioButton[] rbuttons { get; set; } public CheckBox[] checkboxes { get; set; } } public static class F
public class AnswerForm
{
public RadioButton[] rbuttons { get; set; }
public CheckBox[] checkboxes { get; set; }
}
public static class FormExtension
{
public static void Visible(this Form[] elem, bool state)
{
foreach (var item in elem)
item.Visible = state;
}
}
但是当我试着叫它
answerForm.rbuttons.Visible(true);
无法识别扩展方法。它们都在同一名称空间中,因此不能是包含错误或类似错误。RadioButton和
复选框
类都继承自:
单选按钮
和复选框
类都继承自:
扩展方法需要一个
表单[]
,而rbuttons数组的类型是RadioButton
static class FormExtension
{
public static void Visible(this Control[] elem, bool state)
{
foreach (var item in elem)
item.Visible = state;
}
}
将其更改为上面的示例,其中类型为Control[]
,将允许RadioButton[]
和CheckBox[]
使用extensionmethod;以及任何其他控制权
如果您想更具体,不允许使用某些控件类型,请将其更改为按钮库[]
;RadioButton和CheckBox都继承自ButtonBase
对于上述解决方案,ReSharper实际上给了我一个警告,因为它可能会导致运行时错误:“从RadioButton[]到ButtonBase[]的Co-variant数组转换可能会导致写操作时出现运行时异常”
下面的解决方案解决了这个问题。同样,它也可以更改为控制
public static void Visible<T>(this IEnumerable<T> elem, bool state) where T: ButtonBase
{
foreach (var item in elem)
item.Visible = state;
}
publicstaticvoid可见(此IEnumerable元素,bool状态),其中T:ButtonBase
{
foreach(要素中的var项目)
可见项=状态;
}
最后一点注意,我已将数组更改为IEnumerable。这扩展了用法;正如注释中所建议的那样。您的扩展方法需要一个
表单[]
,而rbuttons数组的类型为RadioButton
static class FormExtension
{
public static void Visible(this Control[] elem, bool state)
{
foreach (var item in elem)
item.Visible = state;
}
}
将其更改为上面的示例,其中类型为Control[]
,将允许RadioButton[]
和CheckBox[]
以及任何其他控件使用扩展方法
如果您想更具体一些,并且不允许使用某些控件类型,请将其更改为ButtonBase[]
;RadioButton和CheckBox都继承自ButtonBase
对于上述解决方案,ReSharper实际上给了我一个警告,因为它可能会导致运行时错误:“从RadioButton[]到ButtonBase[]的Co-variant数组转换可能会导致写操作时出现运行时异常”
下面的解决方案可以解决这个问题。同样,它也可以更改为控制
public static void Visible<T>(this IEnumerable<T> elem, bool state) where T: ButtonBase
{
foreach (var item in elem)
item.Visible = state;
}
publicstaticvoid可见(此IEnumerable元素,bool状态),其中T:ButtonBase
{
foreach(要素中的var项目)
可见项=状态;
}
最后注意,我已将数组更改为IEnumerable。这扩大了使用范围;正如注释中所建议的。将可见方法参数从
表单
更改为IEnumerable
,因为复选框和单选按钮都是控件
public class AnswerForm
{
public RadioButton[] rbuttons { get; set; }
public CheckBox[] checkboxes { get; set; }
}
public static class FormExtension
{
public static void Visible(this IEnumerable<Control> elem, bool state)
{
foreach (var item in elem)
{
item.Visible = state;
}
}
}
公共类应答器表单
{
公共单选按钮[]rbuttons{get;set;}
公共复选框[]复选框{get;set;}
}
公共静态类FormExtension
{
公共静态无效可见(此IEnumerable元素,布尔状态)
{
foreach(要素中的var项目)
{
可见项=状态;
}
}
}
将可见方法参数从表单更改为IEnumerable
,因为复选框和单选按钮是控件
public class AnswerForm
{
public RadioButton[] rbuttons { get; set; }
public CheckBox[] checkboxes { get; set; }
}
public static class FormExtension
{
public static void Visible(this IEnumerable<Control> elem, bool state)
{
foreach (var item in elem)
{
item.Visible = state;
}
}
}
公共类应答器表单
{
公共单选按钮[]rbuttons{get;set;}
公共复选框[]复选框{get;set;}
}
公共静态类FormExtension
{
公共静态无效可见(此IEnumerable元素,布尔状态)
{
foreach(要素中的var项目)
{
可见项=状态;
}
}
}
您的表单扩展是否是类公共的
?扩展方法是否需要附加到控件而不是表单?您的表单扩展是否是公共的
?扩展方法是否需要附加到控件而不是表单?您可以通过扩展IEnumerable
而不是Control[]
。这确实更好,@stakx。我将相应地编辑我的答案。如果该方法没有与现有属性同名(Visible
),Resharper可能不会给出警告。我会将扩展方法重命名为,例如,MakeVisible
,或者SetVisible
,或者干脆Show[All]
。使用动词而不是形容词暗示该方法将改变state.PS。我发现最后的代码示例有点令人困惑。它是一般性(IEnumerable
而不是[]
)和特殊性(按钮库
而不是控件
)之间的特殊组合。从说教的角度来看,决定一般性或特殊性可能更有意义,但不能同时决定两者。事实上,这不是问题所在。“从RadioButton[]到ButtonBase[]的共变量数组转换可能导致写入操作时出现运行时异常”。它与命名无关。通过扩展IEnumerable
而不是Control[]
,您可以使该扩展方法更加通用。这确实更好,@stakx。我将相应地编辑我的答案。如果该方法没有与现有属性同名(Visible
),Resharper可能不会给出警告。我会将扩展方法重命名为,例如,MakeVisible
,或者SetVisible
,或者干脆Show[All]
。使用动词而不是形容词暗示该方法将改变state.PS。我发现最后的代码示例有点令人困惑。这是一种普遍性(