Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何更新类代码使其与类型无关_C#_Winforms - Fatal编程技术网

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()
我需要访问我前面提到的一些属性。如何做到这一点,以避免复制/粘贴266行代码,这些代码构成了目前只能使用控件对象的类

除了尝试使用泛型之外,我还尝试看看是否可以使用基类类型对象而不是控件,但这导致了我目前遇到的泛型问题。我不再能够访问与控件、按钮和标签关联的成员

为了消除任何混淆,下面的示例(非工作)代码是我试图完成的

公共类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
 }