C#如何在一个方法中引用另一个方法的变量

3
有时候我想在方法B中使用很多方法A的变量。通常来说,将所有变量传递给这个方法是相当麻烦的,特别是如果我不得不多次这样做(但不能简单地复制粘贴,因为有些东西会改变)或者我只是懒得这样做。
是否有类似于“内部方法”的东西?或者有没有一些概念可以轻松处理这个问题?
我想做的事情:
    public void A()
    {
        int a = 4;
        string b = "Hello World";

        B(ref vals);

        //Or like so
        C(ref current);
    }

    public void B(ref AllValues)
    {
        a = 3;
        ...
    }

    public void C(ref MethodThatSharesAllValues method)
    {
        method.a = 3;
        ...
    }

目前无法实现,你需要在值之间传递。不过,C# 7 将会引入局部函数。 - DavidG
2
创建一个封装了所需字段的对象。将该对象传递给其他部分。 - Jonesopolis
4个回答

2

如果它们都在同一个类中

您可以将它们配置为类变量:

public class MyClass{

    //set this as private/protected/public or nothing and you can also set a default value
    int a;

    public void A()
    {
        a = 4;
        string b = "Hello World";

        B();

        C();
    }

    public void B()
    {
        a = 3;
        ...
    }

    public void C()
    {
        a = 3;
        ...
    }
}

Elseway

public static class MyClassA{
  public static int a = 0;
  
  public static void MethodA(){
    this.a = 3;
  }
}

现在你可以通过方法B来访问MyClassA。

int myExValueA = MyClassA.a;

否则你需要把它们作为参数传递

希望这有所帮助


谢谢。当然,那是最好的方法。我完全没有想到,不知道为什么... - Gabriel Weidmann

1
你可以创建一个类来保存你的参数,然后只传递该类的实例。
public void metA(Parameters input)
{
    input.a = 5;
    input.c = "hello";
    metB(input);
}

public void metB(Parameters input)
{
    input.b = 10;
}

public class Parameters
{
    public int a;
    public int b;
    public string c;
}

1
你可以在类头中声明变量为静态变量,并根据需要使用它们,如果在同一类中,则为私有变量,对于子类则为受保护的变量,否则为内部或公共变量。或者像这样将变量装箱到一个类中:
public class Foo
{
    public int A { get; set; }
    public int B { get; set; }
    public string C { get; set; }
}

如果传递的变量类型相同,您可以使用数据结构,例如int[]或string[]或List<int>或List<string>,并且不需要使用ref进行传递,但这种方法的缺点是经常会出现以下情况:您不会使用结构中的所有变量,就像使用类装箱变体一样。

1

类似以下内容:

public void foo() {
    int a = 10;
    // ...
}

public void foo_bar() {
    // "a" is not in scope for foo_bar, so this won't compile
    a = 20;
    // ...
}

肯定是无效的。不过我认为这不是你在问题中想表达的。

你可以使用closures来做一些类似于你所要求的事情,但是它们有点棘手。基本上,像这样的东西是有效的(如果语法有点错误,请原谅我,因为我不在IDE前):

Func<int> GetCounter() {
     int count = 0;

     // This will capture the count variable from its context
     Func<int> method = () => ++count;

     return method;
}

虽然有相当数量的语言(包括现在的某些C++版本)具有闭包(或某些类似变体),但这些语言在闭包的工作方式上似乎缺乏一致性(例如,在捕获“计数”变量后是否应该使其不可变),因此重要的是检查您正在使用的语言的文档(在本例中为C#)以了解它们的确切工作方式。
至于我提供的第一个代码示例,我怀疑那可能不是你所问的,但只是简单地偏离一下话题,你可能真的不想让它被允许(我再次怀疑这不是你所询问的语法/语义),因为它很快就会导致意外/未定义的行为。例如:
  • 如果你有一个本地变量 a,在 Foo() 中初始化,在运行 Foo() 之前在 Foo_Bar() 中引用它,它的值应该是什么?
  • 如果你运行 Foo() 来初始化变量,在 Foo_Bar() 中编辑变量,然后再次运行 Foo(),你应该重新初始化变量还是让它保持 Foo_Bar() 设置的值?
  • 在方法调用完成后,对于本地变量进行垃圾回收是否安全,或者可能会再次引用它?

参见以下内容:

public class SomeObject
{
   public int SomeProperty { get; set; } = 6;
   // ...
}

public class SomeOtherObject
{
   // ..
}

void foo() {
    // What is the content of "a" before foo() runs?
    object a = new SomeObject();

    // Which "a" should this refer to - the one in foo() or the one in foo_bar()?
    // Also, is this a valid cast given that we haven't specified that SomeOtherObject can be cast to SomeObject?
    var b = (SomeObject)a;

    // If we run foo() again, should "b" retain the value of SetProperty or set it back to the initial value (6)?
    b.SetProperty = 10;

    // ...

    // Is it safe to garbage collect "a" at this point (or will foo_bar refer to it)?
}

void foo_bar() {
    object a = new SomeOtherObject();
    // ...
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接