簡體   English   中英

無法將派生類強制轉換為其基類型

[英]Can't cast a derived class to its base type

我的課程中有幾個對話框,我正在嘗試使用函數初始化它們:

    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);

error CS1503: Argument 1: cannot convert from 'ref Microsoft.Win32.OpenFileDialog' to '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撰寫的此博客文章:
為什么ref和out參數不允許類型變化?

無論如何:在這種情況下不要使用ref

問題出在ref關鍵字上。 它允許您替換調用者的引用。

例如:

static void Main(string[] args)
{
    string str = "hello";

    SomeFunction(ref str);

    Console.WriteLine(str); // outputs "world"
}

static void SomeFunction(ref string obj)
{
    obj = "world";
}

現在想象你可以使用基類,你有這種情況:

static void Main(string[] args)
{
    OpenFileDialog dialog = new OpenFileDialog();

    SomeFunction(ref dialog);
}

static void SomeFunction(ref FileDialog obj)
{
    obj = new SaveFileDialog();
}

SomeFunction的代碼有效,因為SaveFileDialogFileDialog 但是,在Main函數中,您將SaveFileDialog分配給OpenFileDialog ,這是不可能的。 這就是為什么,當使用ref關鍵字時,您必須提供完全相同類型的引用。

要解決您的問題,只需刪除ref關鍵字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM