【问题标题】:C# accesing non static member in a static functionC#在静态函数中访问非静态成员
【发布时间】:2011-09-30 17:59:04
【问题描述】:

所以我有一个函数:

List<string> names = new string();

private static void getName(string name)
{
    names.add(name);
}

当我尝试编译时,我得到: “非静态字段需要对象引用”通知。 我必须做些什么才能使这个成员(名称)与 getName 兼容?

我需要它是非静态的或转换的,因为我想将结果放入其他非静态函数和表单中。

【问题讨论】:

  • 为什么 getName 首先是静态的?
  • 这是一个假设的简化情况。
  • 方法名应该是AddName(string name)

标签: c# static member


【解决方案1】:

您需要告诉系统哪个您感兴趣的名称列表。它是对象状态的一部分,是类的实例...但是是哪一个?也许您已经创建了该类的 几个 个实例 - 也许您已经创建了该类的 no 个实例。静态方法对此不可见 - 那么您希望它从哪个实例中获取 names 变量值?

再举一个例子,假设我们有一个这样的类:

public class Person
{
    public double MassInGrams { get; set; }
    public double HeightInMetres { get; set; }

    public static double ComputeBodyMassIndex()
    {
        // Which person are we interested in?
    }
}

Person p1 = new Person { MassInGrams = 76203, HeightInMetres = 1.8 };
Person p2 = new Person { MassInGrams = 65000, HeightInMetres = 1.7 };

double bmi = Person.ComputeBodyMassIndex();

您希望结果是什么?您已要求 Person 类计算“BMI”,但没有告诉它要计算谁的 BMI。您需要向其提供该信息。

适合您情况的一些选项:

  • names 改为静态
  • 将方法更改为实例方法
  • 传入一个类的实例
  • 创建一个类的实例,可能会返回它
  • 以其他方式获取类的实例

顺便说一句,这是一个非常奇怪的方法名称,它添加了一个名称。这也有点不合常规......

【讨论】:

  • 能否再解释一下实例方法的解决方案。使用我创建的示例。我相信名称目前是一个参考。
  • @Drake: names 将是对 List&lt;string&gt; 实例的引用 - 您需要对包含类的实例的引用。查看我的Person 示例,以了解应该说明为什么会出现问题的示例。一旦你理解了这个问题,你可能会更清楚该怎么做。
  • @Drake - 为了ComputeBodyMassIndex(),系统需要知道要在哪个人身上进行计算。所以你传入一个 Person 对象,你的 ComputeBodyMassIndex() 现在接收那个人 public static double ComputeBodyMassIndex(Person p) 然后可以计算 BMI。在您的情况下,您想将string 添加到List&lt;string&gt;。问题是names 是该类的一部分,当您创建该类的对象时,您可以直接访问名称。
  • 它不是我调用的函数,因此不适用。它是我需要访问的一个 win32 回调函数。回调是静态的,我的列表不是。
  • @Drake:当你说它是一个 win32 回调函数时,不清楚你的意思。你的意思是你以某种方式将它作为委托传递给 Win32 函数,然后它被回调?如果是这样,只需将其设为实例方法,并使用正确的目标构造一个适当的委托。
【解决方案2】:

如果您想在静态方法内部使用names,则需要将其设为静态:

 // If this is static, you can use it from your static method
 static List<string> names = new List<string>();

问题在于getName在您的类型上定义的,而不是在该类型的实例上。但是,names 已定义,因此您的类型的每个 instance 都有自己的值。

【讨论】:

  • @Drake:您可以从实例中访问静态成员,但反之则不行。
【解决方案3】:

names 是一个存在于类实例中的对象,例如MyClass mc = new MyClass(); 然后你可以访问mc.names。静态字段可以在没有类实例的情况下仅使用类名来调用,例如MyClass.getName(""); 会起作用。因此,当您从逻辑上思考时,该类不包含名称,只有“该类的实例”包含它。因此,您要么将该列表设为静态,并且当您调用 MyClass.names 时它在任何地方都是“相同的列表实例”,或者将 getName 方法设为非静态,它只会从实例中调用,因此不会有 MyClass.getName("")有可能,但mc.getName(""); 这取决于你到底想做什么。

【讨论】:

    【解决方案4】:

    静态方法不能访问类字段。要么将名称设为静态,要么将 getName() 设为非静态。 “兼容”是什么意思。问问自己...该方法是否需要是静态的?它的目的是什么?您打算如何使用它?

    【讨论】:

      【解决方案5】:

      你不能这样访问它,你需要实例化包含一个成员的类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-26
        • 1970-01-01
        • 2016-02-09
        相关资源
        最近更新 更多