4

クラスにいくつかのダイアログがあり、それらを関数で初期化しようとしています:

    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

私もジェネリックを使用しようとしましたが、うまくいきませんでした。私は何が欠けていますか?

4

2 に答える 2

4

ref最善の解決策は、キーワードを削除することです。この場合、実際には必要ありません。

メソッドが渡した変数を再割り当てできる必要がある場合にのみ必要です。これはほとんどありませref通常は、値を返すか、オブジェクトを直接操作するだけで十分です。

ただし、コンパイラ エラーは、メソッドが必要とする正確な型の変数を渡す必要があるという事実から発生します。このような:

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

結局、refパラメーターとして渡された元の変数は、メソッドによって再割り当てされる可能性があります。

SaveFileDialogタイプ の元の変数にa を代入するとどうなるでしょうOpenFileDialogか? 私たちが知っている世界は終わります。そのため、 type の一時変数を作成する必要がありますFileDialog。型システムにより、メソッドは任意の派生クラスのオブジェクトをその変数に割り当てることができます。

この興味深いトピックの詳細については、Eric Lippert によるブログ エントリを参照
してください。

refとにかく:この場合は使用しないでください。

于 2012-12-19T12:56:39.387 に答える
0

問題は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は有効SaveFileDialogですFileDialog。しかし、関数内で aを aMainに代入することになりますが、これは不可能です。そのため、キーワードを使用するときは、まったく同じタイプの参照を提供する必要があります。SaveFileDialogOpenFileDialogref

ケースの問題を解決するには、refキーワードを削除するだけです。

于 2012-12-19T13:01:49.553 に答える