C# 使用GetType()在事件处理程序中强制转换发件人对象。名称
我有一个用于Textbox和RichTextBox的事件处理程序。 代码是相同的,但是 在handler#1中,我会: 相应地,在处理程序2中:C# 使用GetType()在事件处理程序中强制转换发件人对象。名称,c#,late-binding,C#,Late Binding,我有一个用于Textbox和RichTextBox的事件处理程序。 代码是相同的,但是 在handler#1中,我会: 相应地,在处理程序2中: TextBox tb = (TextBox)sender 这样我就可以完全操纵发送控件。 我想知道的是如何根据发送对象的类型使用 sender.GetType().Name 然后在运行时创建控件并使用它。这样,我只需要一个事件处理函数:更少的代码、更少的错误、更易于维护和删除:-)而不是您可以使用的类型名称“” 如果您只想知道类型而不需要对象引用:
TextBox tb = (TextBox)sender
这样我就可以完全操纵发送控件。
我想知道的是如何根据发送对象的类型使用
sender.GetType().Name
然后在运行时创建控件并使用它。这样,我只需要一个事件处理函数:更少的代码、更少的错误、更易于维护和删除:-)而不是您可以使用的类型名称“” 如果您只想知道类型而不需要对象引用:
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";
}
强制转换只能在编译时完成,因此您需要知道希望在编译时强制转换到的类型。因此,在强制转换时不能使用运行时类型(由GetType()返回) 如果您正在查找多态性,则可以通过反射访问Name属性。不过,为了能够重用事件处理程序,我不会这么做
如果需要强类型,两个发送方上的公共基类或接口是唯一的选择。您永远不必强制转换。我开始的时候也这么想,这个“模式”是不正确的,也不符合逻辑 您最好使用以下方法:
if (sender is TextBox)
{
TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
RichTextBox rtb = (RichTextBox)sender;
}
else
{
// etc
}
如果代码相同,您需要注意吗?我想知道,如果将角色转换为
控制
是否不能提供您所需的一切
一个复杂的处理程序并不一定比几个简单的处理程序好。无论哪种方式,如果必须走这条路线,最好使用“as”/“is”(它不依赖于字符串等):
根据需要的属性,可以将发送方强制转换为TextBoxBase,因为TextBox和RichTextBox都继承自该子类。如果不想重复代码,则可以强制转换这两个控件,将常用操作重构为一个单独的方法,该方法将TextBoxBase作为参数。在事件处理程序中,将控件转换为System.Windows.Forms.TextBoxBase,因为这两个控件都是从TexbBoxBase派生的,并调用该方法
请注意,如果您需要这些控件中任何一个的特定属性,则此重构将不起作用。我知道这是一篇非常古老的文章,但在Framework 4中,您可以将发送者转换为控件:
Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();
注意:您只能引用所有不同控件的共同控件(即文本)。上述代码的通用版本:
public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
T thing = item as T;
if (thing != null)
{
action(thing);
}
}
不完美,但很方便。您还可以使用一个内联临时变量为您处理强制转换
if (sender is RichTextBox tb)
{
// ... //
}
else if (sender is TextBox tb)
{
// ... //
}
你能举一个在两个这样的类型之间共享的多态方法或属性的例子吗?但是没有被一个公共接口公开?这是可以的,但是@Chris suggestion更好。由于你要立即对对象执行某些操作,这将为你节省额外的施法时间。一旦你确定了对象的类型,你实际上是在施法,所以你必须施法,但这绝对是正确的方法,因为它不依赖(缓慢的)反射。
Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();
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));
if (sender is RichTextBox tb)
{
// ... //
}
else if (sender is TextBox tb)
{
// ... //
}