3

WPF と .NET 4.0 を使用します。

完了時に関数を起動するために使用WebClientおよび使用していくつかのデータをダウンロードしています。DownloadStringCompletedEventHandlerDownloadCompletedCallback

私が抱えている問題は、DownloadCompletedCallbackが呼び出されたときに、メイン フォームにラベルの内容を設定しようとしてエラーが表示されることです。

非静的フィールド、メソッド、またはプロパティ「Armory.MainWindow.lblDebug」にはオブジェクト参照が必要です。

関数DownloadCompletedCallbackが static として宣言されているためだと理解していますが、それが重要な理由はわかりません。

これが私が使用しているコードです。

public static void DownloadHTML(string address)
{
    WebClient client = new WebClient();

    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadCompletedCallback);

    client.DownloadStringAsync(new Uri(address));
}

private static void DownloadCompletedCallback(Object sender, DownloadStringCompletedEventArgs e)
{
    if (!e.Cancelled && e.Error == null)
    {
        lblDebug.Content = (string)e.Result;
    }
}
4

5 に答える 5

3

関数 DownloadCompletedCallback が static として宣言されているためだと理解していますが、それが重要な理由はわかりません。

C#仕様から:

static 修飾子で宣言されたメソッドは static メソッドです。静的メソッドは特定のインスタンスでは動作せず、静的メンバーに直接アクセスすることしかできません。static 修飾子なしで宣言されたメソッドはインスタンス メソッドです。

インスタンス メソッドは特定のインスタンスで動作し、静的メンバーとインスタンス メンバーの両方にアクセスできます。インスタンスメソッドが呼び出されたインスタンスは、this として明示的にアクセスできます。これを静的メソッドで参照するとエラーになります。

これは、静的メソッドがオブジェクトの一部ではないため、オブジェクトと対話できないためです。それらは状態の概念を持たないクラスに関連付けられているため、それを呼び出すと、静的メソッドは非静的オブジェクト変数がどのオブジェクトと対話する必要があるかわかりません。

禁止されている理由の例:

Class Example{...}

var ExampleOne = new Example();
var ExampleTwo = new Example();

Example.CallStaticMethod();

では、どの非静的変数と対話する必要があるのでしょうか? または である必要がありますExampleOneExampleTwo、または単に null 参照例外をスローする必要があります。最初の 2 つのケースでは、システムがどちらと対話する必要があるかを知る方法がありません。3 つ目については、それを呼び出すにはインスタンスが必要になるため、実際には静的ではありません。したがって、非静的メソッドのプロパティなどへのアクセスは禁止する必要があります。

于 2011-03-02T14:26:57.810 に答える
2

静的メソッドはクラスレベルで存在し、特定のユーザー コントロール インスタンスを認識しません。すべてのラベルなどは、ユーザー コントロール クラスの特定のインスタンスで宣言されます。アプリケーションのさまざまな場所で宣言されているものが多数ある可能性があります。静的メソッドは、ユーザー コントロールのそのようなすべてのインスタンスに存在します。

たとえば、さまざまな場所に 5 つのユーザー コントロールが存在する場合、それらはすべて同じ静的メソッドを共有し、そのメソッドはたまたまそれを呼び出した特定のインスタンスにアクセスする方法がありません。

于 2011-03-02T14:26:18.153 に答える
0

lblDebugこのクラスのさまざまなインスタンスにさまざまなが存在する可能性があるため、これは重要です。関数は特定のインスタンスに関連付けられていないため(宣言したためstatic)、コードはlblDebug意味を推測できません。

単一lblDebugのものだけが必要な場合は、静的であると宣言することもできますが、そうする前に、これが何を意味するかを慎重に検討してください。

于 2011-03-02T14:27:52.520 に答える
0

別のスレッドにあるため、lblDebug にアクセスできないことも原因だと思います。(DownloadCompletedCallback は非同期であるため、別のスレッドで実行されます)。親からディスパッチャ オブジェクトを使用して lblDebug を呼び出す必要があります。ただし、呼び出しを検索する必要がありますが、正確なコードについては、ここにビジュアルスタジオがありません。

于 2011-03-02T14:35:42.083 に答える
0

静的メソッドでlblDebugを使用できませんでした。代わりに、コールバックを受け入れるように DownloadHTML メソッドを変更できます。

public static void DownloadHTML(
     string address, 
     DownloadStringCompletedEventHandler callWhenCompleted)
{
    WebClient client = new WebClient();

    client.DownloadStringCompleted += 
        new DownloadStringCompletedEventHandler(callWhenCompleted);

    client.DownloadStringAsync(new Uri(address));
}

private void DownloadCompletedCallback(
    Object sender, DownloadStringCompletedEventArgs e)
{
    if (!e.Cancelled && e.Error == null)
    {
        lblDebug.Content = (string)e.Result;
    }
}

使用:

DownloadHTML(
     "http://stackoverflow.com/questions/5168788/c-static-scope-issue",
     this.DownloadCompletedCallback);
于 2011-03-02T14:32:37.777 に答える