我有一个Textbox和RichTextBox的事件处理程序。 代码相同,但
在处理程序#1中我做:
RichTextBox tb = (RichTextBox)sender
相应地在处理程序#2中:
TextBox tb = (TextBox)sender
这样做我可以完全操纵发送控件。 我想知道的是如何使用
将发送对象根据其类型转换为Textbox或RichTextboxsender.GetType().Name
然后在运行时创建控件并使用它。这样我只需要一个事件处理函数:更少的代码,更少的错误,更容易维护和干: - )
答案 0 :(得分:29)
你永远不必投。
当我开始时,我曾经以同样的方式思考,这种“模式”是不正确的,而且不合逻辑。你最好的选择是使用类似的东西:
if (sender is TextBox)
{
TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
RichTextBox rtb = (RichTextBox)sender;
}
else
{
// etc
}
答案 1 :(得分:6)
我知道这是一篇非常古老的帖子,但在Framework 4中,您可以将发件人转换为控件:
Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();
请注意,您只能引用所有不同控件共有的控件(即Text)。
答案 2 :(得分:4)
RichTextBox textbox = sender as RichTextBox;
if (textbox != null)
{
// do stuff as a rtb
textbox.Text = "I'm a rtb";
return;
}
TextBox textbox = sender as TextBox;
if (textbox != null)
{
// do stuff as a textbox
textbox.Text = "I'm a textbox";
}
答案 3 :(得分:3)
转换只能在编译时完成,因此您需要知道在编译时要转换的类型。因此,在转换时不能使用运行时类型(由GetType()返回)。
如果是您正在寻找的多态,您可以通过反射访问Name属性。我不会这样做只是为了能够重用事件处理程序。
如果您想要强类型,两个发件人的公共基类或接口是唯一的方法。
答案 4 :(得分:3)
根据您需要的属性,您可以将发件人转换为TextBoxBase,因为TextBox和RichTextBox都从该子类继承。
答案 5 :(得分:2)
您可以使用“is”而不是类型名称。
如果您只想知道类型并且不需要对象引用:
if (sender is RichTextBox)
{
// ...
}
else if (sender is TextBox)
{
// ...
}
但是你通常需要这个对象:C#7有一个很好的语法,允许你测试并获取内联值:
if (sender is RichTextBox richTextBox)
{
richTextBox.Text = "I am rich";
}
else if (sender is TextBox textBox)
{
textBox.Text = "I am not rich";
}
答案 6 :(得分:1)
您还可以使用内联临时变量来处理演员表。
if (sender is RichTextBox tb)
{
// ... //
}
else if (sender is TextBox tb)
{
// ... //
}
答案 7 :(得分:0)
如果代码相同,您需要关心吗?我想知道施放到Control
是否会给你所需的一切......
一个复杂的处理程序不一定比几个简单的处理程序更好。无论哪种方式,如果你有去这条路线,“as”/“is”是可取的(它不依赖于字符串等):
TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...
答案 8 :(得分:0)
如果您不想重复代码,那么您可以转换两个控件,将常用操作重构为一个单独的方法,该方法将TextBoxBase作为参数。在您的事件处理程序中,处理程序将控件转换为System.Windows.Forms.TextBoxBase,因为两个控件都是从TexbBoxBase派生的,并调用该方法。
请注意如果您需要任何这些控件的特定属性,那么这种重构将不起作用。
答案 9 :(得分:0)
上述代码的通用版本:
public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
T thing = item as T;
if (thing != null)
{
action(thing);
}
}
用作:
CastAndUse(sender, new Action((foo) => foo = bar));
不完美,但很方便。