c# – 无法将派生类强制转换为其基类型

我的课程中有几个对话框,我正在尝试使用函数初始化它们:

    private void InitializeFileDialog(ref FileDialog fileDialog)
    {
        fileDialog.Filter = "Word Documents|*.doc|Excel Worksheets|*.xls|PowerPoint Presentations|*.ppt" +
         "|Office Files|*.doc;*.xls;*.ppt" +
         "|All Files|*.*";
        fileDialog.DefaultExt = "txt";
    }

问题是我打电话给它:

    InitializeFileDialog(ref dialog);

错误CS1503:参数1:无法从’ref Microsoft.Win32.OpenFileDialog’转换为’ref Microsoft.Win32.FileDialog’

我试图施放,但由于某种原因它不能.有什么问题?是因为FileDialog是抽象的吗?我试着查看是否是原因,但我找不到任何有用的东西.

以下是Microsoft.Win32中的声明:

public abstract class FileDialog : CommonDialog
public sealed class OpenFileDialog : FileDialog

我也尝试使用泛型,但它没有用.我错过了什么?

解决方法:

最好的解决方案是删除ref关键字.在这种情况下真的不需要.

你只需要ref,如果你的方法应该能够重新分配你传入的变量,这几乎不应该.返回一个值,或者直接使用该对象,通常就足够了.

但是,编译器错误来自于您需要传入方法所需的确切类型的变量.像这样:

FileDialog baseDialog = fileDialog;
// baseDialog might be a different object when this returns
InitializeFileDialog(ref baseDialog); 

毕竟,作为ref参数传递的原始变量可以由您的方法重新分配.

现在如果将SaveFileDialog分配给OpenFileDialog类型的原始变量会发生什么?我们所知道的世界将会结束.这就是为什么你需要创建一个FileDialog类型的临时变量.类型系统允许您的方法将任何派生类的对象分配给该变量.

有关此有趣主题的更多信息,请参阅Eric Lippert撰写的此博客文章:
Why do ref and out parameters not allow type variation?

无论如何:在这种情况下不要使用ref.

上一篇:在子类java中更改类变量类型


下一篇:java – 对超类对象的子类引用