C# 如何更新类代码使其与类型无关
问题:我目前有一个类,它接受控件类型的对象并执行一些工作。我试图创建一个类,它可以接受控件、按钮或标签对象。我可以使这项工作,但它将涉及我复制和粘贴类两次以上。一个用于按钮,另一个用于标签。除了类型之外,被调用的逻辑和成员完全相同。我已将我希望传达的概念简化如下:C# 如何更新类代码使其与类型无关,c#,winforms,C#,Winforms,问题:我目前有一个类,它接受控件类型的对象并执行一些工作。我试图创建一个类,它可以接受控件、按钮或标签对象。我可以使这项工作,但它将涉及我复制和粘贴类两次以上。一个用于按钮,另一个用于标签。除了类型之外,被调用的逻辑和成员完全相同。我已将我希望传达的概念简化如下: //此类当前仅对控件对象起作用 公共类takeControlType { 公共控制类型(控制) { string objectName=control.Name.ToString(); } } 我可以复制粘贴上面的代码,并通过重载类
//此类当前仅对控件对象起作用
公共类takeControlType
{
公共控制类型(控制)
{
string objectName=control.Name.ToString();
}
}
我可以复制粘贴上面的代码,并通过重载类构造函数使其工作,如下所示:
公共类takeAnyType
{
公共takeAnyType(控制)
{
string objectName=control.Name.ToString();
}
公共takeAnyType(按钮)
{
string objectName=button.Name.ToString();
}
公共takeAnyType(标签)
{
string objectName=label.Name.ToString();
}
}
我认为这似乎是生产力的拖累,对吗?我希望我可以重用相同的逻辑,尽管类型不同,因为我唯一需要替换的是类型。在我的类中实现的逻辑和属性对于控件、按钮和标签是完全相同的。我曾经研究过泛型,但由于我正在提取控件、按钮或标签的特定属性和方法,因此我似乎无法让泛型处理对象属性,例如.Name或.Width或.Capture。泛型类型为我提供的唯一方法是
- 等于()
- GetHashCode()
- GetType()
- ToString()
公共类takeAnyType
{
公共takeAnyType(anyType obj)
{
字符串objectName=obj.Name.ToString();
obj.Cursor=Cursors.SizeNESW;
对象捕获=真;
物体宽度=20;
obj.Top=100;
}
}
按钮
和标签
类继承自控件
(间接)。这意味着,如果只为控件
创建一个类,则仍然可以将其用于按钮
或标签
类型的对象。你不必为这些创建特殊的类
在C#(通常是OO语言)中,可以将派生类的实例分配给超类的变量。例如,这是有效的C#代码:
答案针对您的示例,但您的问题似乎描述了更多内容—在
标签
s和按钮
s上进行更复杂的登录。一种方法是:
1) 声明一个基类以处理常见问题(例如,您的姓名示例)
2) 为每个标签
和按钮
声明一个类,以处理特定的逻辑
public class ControlHelper
{
public virtual String GetControlName(Control control)
{
return control.Name.ToString();
}
// it is not possible to do the logic on a generic control, so force derived classes to provide the logic
public abstract void DoSomeFancyStuffWithControl(Control control);
// other common functions may come here
}
public class LabelHelper : ControlHelper
{
// you may override virtual methods from ControlHelper. For GetControlName, it should not be the case
public override DoSomeFancyStuffWithControl(Control control)
{
var button = control as Label;
// ...
}
// does not have to be virtual, but allow further inheritance
public virtual String GetText(Label l)
{
return l.Text;
}
// other label specific methods come here
}
public class ButtonHelper : ControlHelper
{
public override DoSomeFancyStuffWithControl(Control control)
{
var button = control as Button;
// ...
}
public virtual bool GetEnabled(Button b)
{
return b.Enabled;
}
// other button specific functions may come here
}
按钮和标签是控件。这意味着您可以为接受
控件的构造函数传递按钮
。您可以将控件作为参数并基于发送方
。。您可以找到类型,例如Control cntrl=(Control)sender;cntrl.Text=“这是一个”+发送方.GetType().ToString()
为什么不这样装饰构造函数public takeAnyType(Control obj)
然后可以在方法内部执行以下操作,cntrl=(obj)sender;objType=sender.GetType();然后你可以动态地创建一个
newobject()`这意味着如果它是一个按钮,你可以根据对象类型创建一个新控件。答案很简单,我实际上对此感到尴尬。非常感谢你的澄清。我已经在我的实际项目中修改了代码,它工作得很好!您是对的,我在程序中遇到的根本问题最终与我的问题或答案没有直接关系。然而,这个答案确实让我发现了一个问题,那就是我是如何尝试使用我的按钮和标签的。现在知道按钮和标签间接地从控件继承,我就能够从一个新的角度来寻找这个问题。感谢您冒充您发布的代码,因为我自己没有在任何“实际”程序中使用过继承。在我最初的研究中,我一直在玩弄遗传,我期待着找到对它的需求。
public class ControlHelper
{
public virtual String GetControlName(Control control)
{
return control.Name.ToString();
}
// it is not possible to do the logic on a generic control, so force derived classes to provide the logic
public abstract void DoSomeFancyStuffWithControl(Control control);
// other common functions may come here
}
public class LabelHelper : ControlHelper
{
// you may override virtual methods from ControlHelper. For GetControlName, it should not be the case
public override DoSomeFancyStuffWithControl(Control control)
{
var button = control as Label;
// ...
}
// does not have to be virtual, but allow further inheritance
public virtual String GetText(Label l)
{
return l.Text;
}
// other label specific methods come here
}
public class ButtonHelper : ControlHelper
{
public override DoSomeFancyStuffWithControl(Control control)
{
var button = control as Button;
// ...
}
public virtual bool GetEnabled(Button b)
{
return b.Enabled;
}
// other button specific functions may come here
}