C# 使用 GetType().Name 在事件处理程序中投射发送者对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/634112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 11:09:13  来源:igfitidea点击:

Cast sender object in event handler using GetType().Name

c#late-binding

提问by tfl

I have an event handler for a Textbox as well as for a RichTextBox. The code is identical, but

我有一个用于文本框和 RichTextBox 的事件处理程序。代码是一样的,但是

In handler #1 i do:

在处理程序 #1 中,我这样做:

RichTextBox tb = (RichTextBox)sender

In handler #2 accordingly:

在处理程序 #2 中相应地:

TextBox tb = (TextBox)sender

Doing so i can fully manipulate the sending control. What i want to know is how can i cast the sending object to Textbox or RichTextbox according to its type using

这样做我可以完全操纵发送控制。我想知道的是如何根据类型将发送对象转换为 Textbox 或 RichTextbox

sender.GetType().Name

and then create the control at runtime and work with it. That way i only need one event handler function: less code, less errors, easier to maintain and DRY :-)

然后在运行时创建控件并使用它。这样我只需要一个事件处理函数:更少的代码,更少的错误,更容易维护和 DRY :-)

采纳答案by Kieron

Depending on what properties you need, you could cast the sender as a TextBoxBase as both the TextBox and RichTextBox both inherit from that sub-class.

根据您需要的属性,您可以将发件人转换为 TextBoxBase,因为 TextBox 和 RichTextBox 都继承自该子类。

回答by Chris S

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";
}

回答by stuartd

Rather than the type name you could use 'is'.

而不是您可以使用“”的类型名称。

If you just want to know the type and don't need an object reference:

如果您只想知道类型而不需要对象引用:

if (sender is RichTextBox)
{
    // ...
}
else if (sender is TextBox)
{
    // ...
}

However you generally do want the object: C#7 has a nice syntax that allows you to test and get the value inline:

但是,您通常确实需要对象:C#7 有一个很好的语法,可以让您测试并获取内联值:

if (sender is RichTextBox richTextBox)
{
    richTextBox.Text = "I am rich";
}
else if (sender is TextBox textBox)
{
    textBox.Text = "I am not rich";
}

回答by Peter Lillevold

Casting can only be done at compile-time and thus you need to know the types that you wish to cast to at compile-time. A runtime Type (as returned by GetType()) can therefore not be used when casting.

转换只能在编译时完成,因此您需要知道您希望在编译时转换为哪些类型。因此,在强制转换时不能使用运行时类型(由 GetType() 返回)。

If it is polymorphism you are looking for you could access the Name property through reflection. I wouldn't go that way though just to be able to reuse event handlers.

如果它是您正在寻找的多态性,则可以通过反射访问 Name 属性。我不会那样做只是为了能够重用事件处理程序。

If you want strong typing, a common base class or interface on the two senders is the only way to go.

如果您想要强类型,则两个发送方的公共基类或接口是唯一的出路。

回答by leppie

You never have to cast. I used to think the same way when I started, this 'pattern' is incorrect, and not really logical.

你永远不必投。刚开始时,我曾经以同样的方式思考,这种“模式”是不正确的,而且不符合逻辑。

Your best bet is to use something like:

你最好的选择是使用类似的东西:

if (sender is TextBox)
{
  TextBox tb = (TextBox)sender;
}
else if (sender is RichTextBox)
{
  RichTextBox rtb = (RichTextBox)sender;
}
else
{
  // etc
}

回答by Marc Gravell

If the code is identical, do you need to care? I wonder if casting to Controlwouldn't give you everything you need...

如果代码相同,你需要关心吗?我想知道是否投射到Control不会给你你需要的一切......

One complex handler is not necessarily better than several simple handlers. Either way, if you haveto go this route, "as"/"is" is preferable (it isn't dependent on strings etc):

一个复杂的处理程序不一定比几个简单的处理程序好。无论哪种方式,如果你必须走这条路,“as”/“is”是更可取的(它不依赖于字符串等):

TextBox tb = sender as TextBox;
if(tb!=null) {/* TextBox specific code */}
...

回答by gk.

if you dont want to repeat the code then you can cast both the controls, refactor the common actions to a separate method which takes TextBoxBase as an argument. And in your event handlers convert the controls to System.Windows.Forms.TextBoxBase as both controls are derived from the TexbBoxBase and call the method.

如果您不想重复代码,那么您可以强制转换两个控件,将常见操作重构为一个单独的方法,该方法将 TextBoxBase 作为参数。并且在您的事件处理程序中,将控件转换为 System.Windows.Forms.TextBoxBase,因为这两个控件都派生自 TexbBoxBase 并调用该方法。

Please note If you need specific properties of any of these controls then this refactoring wont work.

请注意,如果您需要任何这些控件的特定属性,则此重构将不起作用。

回答by Mark Kram

I know this is a very old post but in Framework 4 you can cast the sender as a Control:

我知道这是一篇很老的帖子,但在 Framework 4 中,您可以将发送者转换为 Control:

Control cntrl = (Control)sender;
cntrl.Text = "This is a " + sender.GetType().ToString();

Note you are only able to reference controls that all of the different controls have in common (ie Text).

请注意,您只能引用所有不同控件共有的控件(即文本)。

回答by Josh

Generic version of the above code:

上面代码的通用版本:

public static void CastAndUse<T>(object item, Action<T> action) where T : class
{
    T thing = item as T;

    if (thing != null)
    {
        action(thing);
    }
}

Used as:

用作:

CastAndUse(sender, new Action((foo) => foo = bar));

Not perfect, but handy.

不完美,但很方便。

回答by Chris Stillwell

You can also use an inline-temporary variable to handle the cast for you.

您还可以使用内联临时变量为您处理强制转换。

if (sender is RichTextBox tb)
{
    // ... //
} 
else if (sender is TextBox tb)
{
    // ... //
}