C#静态范围问题

时间:2011-03-02 14:24:40

标签: c# wpf oop scope downloadstring

使用WPF和.NET 4.0。

我正在使用WebClient下载一些数据,并在完成后使用DownloadStringCompletedEventHandler启动我的DownloadCompletedCallback功能。

我遇到的问题是,当调用DownloadCompletedCallback时,我正在尝试在主窗体上设置标签的内容,并显示错误。

非静态字段,方法或属性'Armory.MainWindow.lblDebug'需要对象引用。

我理解这是因为函数DownloadCompletedCallback被声明为静态但我不明白为什么这很重要。

这是我正在使用的代码。

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

5 个答案:

答案 0 :(得分:3)

  

我明白这是因为   函数DownloadCompletedCallback是   声明为静态,但我没有   明白为什么这很重要。

来自C#规范:

  

用静态声明的方法   修饰符是一种静态方法。静止的   方法不适用于特定的   实例并且只能直接访问   静态成员。声明了一个方法   没有静态修饰符是一个   实例方法。

     

实例方法   在特定的实例上运行   可以访问静态和实例   成员。一个实例   调用实例方法即可   显式访问为此。它是一个   在静态中引用此错误   方法

这是因为静态方法不是对象的一部分,所以它们不能与任何东西进行交互。它们与没有状态概念的类相关联,所以当你调用它时,静态方法不知道它应该与哪个对象进行交互的非静态对象变量。

禁止这样做的一个例子:

Class Example{...}

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

Example.CallStaticMethod();

现在问题是它应该与哪些非静态变量进行交互?应该是ExampleOne还是ExampleTwo,还是应该抛出空引用异常。在前两种情况下,系统无法知道它应与之交互,因为您从未指定它(或者它是实例方法)。对于第三个,它不是真正的静态,因为你需要有一个实例来调用它。因此,必须禁止访问非静态方法属性等,因为存在太多歧义。

答案 1 :(得分:2)

静态方法存在于级别,并且不知道任何特定的用户控件实例。所有标签等都在用户控件类的特定实例上声明;在你的应用程序中,可能会有许多声明在各个地方声明。所有此类用户控件实例都存在静态方法。

如果你有5个用户控件存在于不同的地方,所有它们共享相同的静态方法,并且该方法无法访问恰好调用它的特定实例

答案 2 :(得分:0)

这很重要,因为在这个类的不同实例中可能有许多不同的lblDebug。您的函数与任何特定实例无关(因为您声明了它static),因此代码无法猜出您的lblDebug是什么意思。

如果你只需要一个lblDebug,你也可以声明那个静态 - 但在你这样做之前要仔细考虑这意味着什么!

答案 3 :(得分: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);

答案 4 :(得分:0)

我认为这也是因为你无法访问lblDebug,因为它在另一个线程上。 (DownloadCompletedCallback是异步的,因此它在另一个线程上执行)。您需要使用其父级的调度程序对象调用lblDebug。你将不得不搜索调用,我没有这里的视觉工作室的确切代码。