使用 GetType().Name 在事件处理程序中强制转换发送者对象
我有一个 Textbox 和 RichTextBox 的事件处理程序。 代码是相同的,但
在处理程序 #1 中我这样做:
RichTextBox tb = (RichTextBox)sender
在处理程序 #2 中相应地:
TextBox tb = (TextBox)sender
这样做我可以完全操纵发送控件。 如何根据使用的类型将发送对象转换为 Textbox
或 RichTextbox
sender.GetType().Name
,然后在运行时创建控件并使用它? 这样我只需要一个事件处理函数:更少的代码,更少的错误,更容易维护并且干燥:-)
I have an event handler for a Textbox and a RichTextBox.
The code is identical, but
In handler #1 I do:
RichTextBox tb = (RichTextBox)sender
In handler #2 accordingly:
TextBox tb = (TextBox)sender
Doing so I can fully manipulate the sending control.
How can I cast the sending object to Textbox
or RichTextbox
according to its type using
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 :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
你永远不必施放。 当我开始时,我也曾以同样的方式思考过,这种“模式”是不正确的,而且不符合逻辑。
你最好的选择是使用类似的东西:
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:
我知道这是一篇非常古老的文章,但在 Framework 4 中,您可以将发送者转换为控件:
请注意,您只能引用所有不同控件共有的控件(即文本)。
I know this is a very old post but in Framework 4 you can cast the sender as a Control:
Note you are only able to reference controls that all of the different controls have in common (ie Text).
您可以使用 'is'。
如果您只想知道类型并且不需要对象引用:
但是您通常确实需要对象:C#7 有一个很好的语法,允许您测试并获取内联值:
Rather than the type name you could use 'is'.
If you just want to know the type and don't need an object reference:
However you generally do want the object: C#7 has a nice syntax that allows you to test and get the value inline:
根据您需要的属性,您可以将发送者强制转换为 TextBoxBase,因为 TextBox 和 RichTextBox 都继承自该子类。
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.
转换只能在编译时完成,因此您需要知道您希望在编译时转换为的类型。 因此,在转换时不能使用运行时类型(由 GetType() 返回)。
如果您正在寻找多态性,您可以通过反射访问 Name 属性。 我不会只是为了能够重用事件处理程序而这样做。
如果您想要强类型,两个发送者上的公共基类或接口是唯一的方法。
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.
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.
If you want strong typing, a common base class or interface on the two senders is the only way to go.
上述代码的通用版本:
用作:
不完美,但方便。
Generic version of the above code:
Used as:
Not perfect, but handy.
您还可以使用内联临时变量来处理转换。
You can also use an inline-temporary variable to handle the cast for you.
如果代码相同,您需要关心吗? 我想知道转换为
Control
是否无法为您提供所需的一切...一个复杂的处理程序不一定比几个简单的处理程序更好。 无论哪种方式,如果您必须走这条路,“as”/“is”是更好的选择(它不依赖于字符串等):
If the code is identical, do you need to care? I wonder if casting to
Control
wouldn't give you everything you need...One complex handler is not necessarily better than several simple handlers. Either way, if you have to go this route, "as"/"is" is preferable (it isn't dependent on strings etc):
如果您不想重复代码,那么您可以强制转换这两个控件,将常见操作重构为以 TextBoxBase 作为参数的单独方法。 在事件处理程序中,将控件转换为 System.Windows.Forms.TextBoxBase,因为这两个控件均派生自 TexbBoxBase 并调用该方法。
请注意,如果您需要任何这些控件的特定属性,那么此重构将不起作用。
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.
Please note If you need specific properties of any of these controls then this refactoring wont work.