Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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#_Oop_Abstract Class - Fatal编程技术网

C# 在方法参数中需要抽象类的子类

C# 在方法参数中需要抽象类的子类,c#,oop,abstract-class,C#,Oop,Abstract Class,我有一个方法可以获取子窗体对象并显示它 public void subFormLauncher(object sender, SubForm f) { if (f == null) { f = new SubForm(this); // This line is problematic f.Show(); } else { if (!f.Visible) { f.

我有一个方法可以获取子窗体对象并显示它

public void subFormLauncher(object sender, SubForm f)
{
    if (f == null)
    {
        f = new SubForm(this);    // This line is problematic
        f.Show();
    }
    else
    {
        if (!f.Visible)
        {
            f.Show();
        }
        f.Activate();
    }
}
VS很生气,因为SubForm是一个抽象类,我不小心实例化了它的一个实例(fair)

有没有办法在subFormLauncher的参数中指定我想要子窗体的子窗体?比如:

public void subFormLauncher(object sender, <T> extends SubForm f)
public void子表单启动器(对象发送方,扩展子表单f)

您可以使用一个接口并在方法调用中请求它。

您可以使用一个接口并在方法调用中请求它

public void subFormLauncher(object sender, SubForm f)
已声明传入的对象必须为“SubForm”类型,问题是您的逻辑正在尝试在此新建一个子表单:

f = new SubForm(this);    // This line is problematic
但由于它的抽象性,您无法创建新的。若删除此项,并且在传递到方法中时不允许子窗体为null,那个么问题就解决了

已声明传入的对象必须为“SubForm”类型,问题是您的逻辑正在尝试在此新建一个子表单:

f = new SubForm(this);    // This line is problematic

但由于它的抽象性,您无法创建新的。如果您删除此项,并且在传递到方法中时不允许子窗体为null,则问题已解决。

整个appraoch中的某些内容似乎“关闭”:

public void subFormLauncher(object sender,SubForm f)
提醒我一个事件(object sender),但它看起来不像事件应该发生的那样

您将表单作为参数传递,这也相当奇怪,更不用说您在表单上所做的工作了。如果你给出了它,你就把它放进了foregroind,如果不是,你就实例化它

你很有可能深陷其中

您将无法指定要创建的确切类型。一种方法可能是在混合中添加一些通用:

public void subFormLauncher<T>(object sender, T f) where T : SubForm 
{
    if (f == null)
    {
        f = new T(this);    // This line is problematic
        f.Show();
    }
    else
    {
        if (!f.Visible)
        {
            f.Show();
        }
        f.Activate();
    }
}
publicsvoid子表单启动器(objectsender,tf),其中T:SubForm
{
如果(f==null)
{
f=新的T(this);//这行有问题
f、 Show();
}
其他的
{
如果(!f.Visible)
{
f、 Show();
}
f、 激活();
}
}

你的整个过程似乎有些“不对劲”:

public void subFormLauncher(object sender,SubForm f)
提醒我一个事件(object sender),但它看起来不像事件应该发生的那样

您将表单作为参数传递,这也相当奇怪,更不用说您在表单上所做的工作了。如果你给出了它,你就把它放进了foregroind,如果不是,你就实例化它

你很有可能深陷其中

您将无法指定要创建的确切类型。一种方法可能是在混合中添加一些通用:

public void subFormLauncher<T>(object sender, T f) where T : SubForm 
{
    if (f == null)
    {
        f = new T(this);    // This line is problematic
        f.Show();
    }
    else
    {
        if (!f.Visible)
        {
            f.Show();
        }
        f.Activate();
    }
}
publicsvoid子表单启动器(objectsender,tf),其中T:SubForm
{
如果(f==null)
{
f=新的T(this);//这行有问题
f、 Show();
}
其他的
{
如果(!f.Visible)
{
f、 Show();
}
f、 激活();
}
}

这有什么帮助?我不能使用接口,因为我需要从表单继承,表单是一个classI-see。我在考虑给抽象类添加一个接口。但正如gmn所示,这也是不需要的。gmn的答案应该很好…这有什么帮助?我不能使用接口,因为我需要从表单继承,表单是一个classI-see。我在考虑给抽象类添加一个接口。但正如gmn所示,这也是不需要的。gmn的答案应该是正确的……您缺少对类型的
new()
约束。另外,您没有使用默认构造函数。所以这显然不会编译。@gnud是对的。将构造函数替换为
f=(T)Activator.CreateInstance(typeof(T),新对象[]{this})将修复此问题。但是您关于事件处理程序的观点是正确的。我想提供一个默认的方法来显示任何给定的表单。我不太明白你想告诉我什么<代码>公共子窗体(frmMain f)
是有效的构造函数。如果构造函数不太可能工作(每个子级可能有一个,也可能没有一个),那么FactoryMethod可能是一个不错的选择;T.父母=这个。为什么这么复杂?@gnud:asumes父项是公共字段/不是只读属性。构造函数输入通常用于不应公开设置/多次设置的值。当然,如果这是真的,那么赋值是最简单的方式。您缺少对类型的
new()
约束。另外,您没有使用默认构造函数。所以这显然不会编译。@gnud是对的。将构造函数替换为
f=(T)Activator.CreateInstance(typeof(T),新对象[]{this})将修复此问题。但是您关于事件处理程序的观点是正确的。我想提供一个默认的方法来显示任何给定的表单。我不太明白你想告诉我什么<代码>公共子窗体(frmMain f)
是有效的构造函数。如果构造函数不太可能工作(每个子级可能有一个,也可能没有一个),那么FactoryMethod可能是一个不错的选择;T.父母=这个。为什么这么复杂?@gnud:asumes父项是公共字段/不是只读属性。构造函数输入通常用于不应公开设置/多次设置的值。当然,如果这是真的,那么赋值就是最简单的方法。