非静态字段、方法或属性需要对象引用

本文关键字:属性 对象引用 方法 静态 字段 | 更新日期: 2023-09-27 18:05:02

嘿,我是c#的新手,我正试图调用函数closeComm()像这样:

    public void closeComm()
    {
        commIRToy.ClosePort();
        commProj.ClosePort();
        commTV.ClosePort();
        commAV.ClosePort();
    }
    public static void loadAnotherRemote()
    {
        closeComm();
    }

然而,这给了我一个错误:非静态字段,方法或属性需要对象引用

当我这样尝试时:

    public static void closeComm()
    {
        commIRToy.ClosePort();
        commProj.ClosePort();
        commTV.ClosePort();
        commAV.ClosePort();
    }
    public static void loadAnotherRemote()
    {
        closeComm();
    }

我能够调用函数,但所有的commIRToy, commProj, commTV和commAV都有一个错误对象引用是非静态字段,方法或属性需要相同的错误,我得到了另一种方式....

非静态字段、方法或属性需要对象引用

您将需要使您的commIRToy, commProj, commTVcommAV字段为静态,或者从loadAnotherRemote方法中删除静态关键字。

非静态方法在类的特定实例上操作。在访问成员变量时,它访问调用它的实例的成员。静态方法不需要调用任何特定的实例。因为它不是通过实例调用的,所以它不能引用任何特定于实例的变量,只能引用静态变量。

在你的例子中,我假设(没有看到所有的代码),你可以使所有的方法和属性静态,使其工作。

这意味着你应该在commIRToy等的声明前面加上static这个词:

static PCComm.CommunicationManager commIRToy = new PCComm.CommunicationManager();

这将使它工作-但我不会说这是最好的设计,从长远来看

您正在获得第一个错误,因为loadAnotherRemote()是静态的,但正在尝试调用非静态的方法。
你得到第二个错误,因为,当你现在调用一个静态方法,变量commIrTroy等是类的实例,而不是静态的。
很难给你一个答案,因为我不确定这些方法的上下文

短答:

试试这个:

public static void loadAnotherRemote()
{
    new TypeThatContainsCloseComm(…).closeComm();
}

长答:

首先,您需要理解static:无论声明了什么,static都不属于任何特定的实例类型,而是属于类型本身。也就是说,如果您有一个静态方法TypeThatContainsCloseComm.closeComm,那么您可以使用: 来调用它
   TypeThatContainsCloseComm.closeComm(…)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
//     name of the type!

然而,所有没有声明static的方法只能在特定的实例上调用,因为它们属于

   var commProj = new TypeThatContainsClosePort();  // <- create a instance here
   commProj.ClosePort();
// ^^^^^^^^
// instance of a type!

现在,回到你的原始代码:

public void closeComm()
{
    commIRToy.ClosePort();
    commProj.ClosePort();
    commTV.ClosePort();
    commAV.ClosePort();
}
public static void loadAnotherRemote()
{
    // this method is static, therefore we are not "within" an object instance
    closeComm();  // ERROR: closeComm is not static, therefore you need
                  // some object instance to call it!
}

白马王子;回到你的第二次尝试:

public static void closeComm()
{
    commIRToy.ClosePort();  // ERROR if commIRToy, commProj, commTV, commAV
    commProj.ClosePort();   //       are not declared static, because we're
    commTV.ClosePort();     //       in a static method and thus "outside" an
    commAV.ClosePort();     //       object instance, yet these fields are
}                           //       declared within one.
public static void loadAnotherRemote()
{
    closeComm();  // this call is fine now, since `closeComm` is static,
                  // no object instance is required to call it.
}

在类的上下文中执行static方法。您可以在任何时候调用classname.StaticMethod(),因为编译器可以清楚地理解它。

省略static时,定义了一个在对象(类的实例)上下文中执行的方法,通常使用new classname();创建。

无法编译对closeComm()的调用,因为编译器不知道要针对哪个对象执行方法。

你可以从实例方法中调用static方法,但不能反过来,除非你有一个上下文对象。

如果您需要在特定对象的上下文中调用closeComm()(可能是因为您有许多实例),则loadAnotherRemote()方法需要对象引用。

c#规范:

10.6.2静态方法和实例方法

当方法声明包含静态修饰符时,该方法是说是静态方法。如果没有静态修饰符,则方法是一个实例方法。

静态方法不对特定的实例进行操作,它是一个静态方法在静态方法中引用this时的编译时错误。

MSDN:

静态成员

静态方法、字段、属性或事件甚至可以在类中调用当没有创建类的实例时。如果有任何类被创建后,它们不能用于访问静态成员。静态字段和事件只存在一个副本,static方法和属性只能访问静态字段和静态。静态成员通常用于表示数据或不随对象状态而改变的计算;为例如,数学库可能包含用于计算的静态方法正弦和余弦

在我看来,你试图用静态方法管理实例。如果是这样,如果您一次只需要管理一个实例,或者使用静态方法管理一个静态实例列表,请考虑使用单例模式。如果不是,那么该方法就不是静态的,因此将是无用的,除非它不仅仅做closeComm();

马克西姆真诚

,

相关文章: