非静态字段、方法或属性需要对象引用
本文关键字:属性 对象引用 方法 静态 字段 | 更新日期: 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
, commTV
和commAV
字段为静态,或者从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();
。
,