【问题标题】:How to get the ref of a variable of a class in C#?如何在 C# 中获取类的变量的引用?
【发布时间】:2020-03-29 05:43:46
【问题描述】:

如何获取类中变量的引用?我正在尝试获取变量的参考,在其他地方使用它,并且需要将更改反映在其栖息地中。

 public class PowerComINC
 {
     static int IMALF1_A = 0; //INSTRUCTOR MALF ID FOR MISC FUNCTION
     static int IMALF2_A = 0; //INSTRUCTOR MALF ID FOR MISC FUNCTION
     static int IMFIRE_A = 0; //INSTRUCTOR MALF ID FOR FIRE 

     public static ref int GetAssociatedGlobals(string variableName)
     {
         // return ref of variableName
     }
}

...

ref int val = ref PowerComINC.GetAssociatedGlobals("IMALF1_A");

val++;

Console.Writeln(PowerComINC.IMALF1_A); //Print 1

【问题讨论】:

  • 首先,它应该是ref int val =。我认为你可以在你的方法中使用return ref IMALF1_A;
  • string variableName 总是让我觉得奇怪。几乎不需要通过名称引用变量。您可以改用Dictionary<string, int>

标签: c# ref


【解决方案1】:

您可以避免使用字典或开关,而是在对象的字段中使用搜索,而不是使用 Type 对象的 GetField() 方法。

而且所有这些 ref 的东西都非常复杂,我发现没有办法从 GetField().GetValue() 结果中生成 ref,所以我宁愿建议你为此制作 getter 和 setter。

由于你的类是静态的,你必须使用 typeof 关键字

而且你的变量不能是私有的,不能用 GetField() 找到

public static int getval (string varname)
        {
            return (int)typeof(PowerComINC).GetField(varname).GetValue(typeof(int));
        }

public static void setval(string varname, int value)
        {
            typeof(PowerComINC).GetField(varname).SetValue(typeof(int), value);
        }

然后在你使用的方法中

int val = getval("IMALF1_A");
val++;
setval("IMALF1_A", val);

【讨论】:

    【解决方案2】:

    您可以简单地创建一个Dictionary<string, int>,将这些信息保存为字符串对和int,而不是依赖于变量的名称。那么你就不需要ref-stuff 了:

    public class PowerComINC
    {
        public Dictionary<string, int> MyDict = new Dictionary<string, int>() 
        { 
            { "IMALF1_A", 0 }, 
            { "IMALF2_A", 0 }, 
            { "IMFIRE_A", 0 } 
        };
    }
    

    现在只需通过键引用一个值:

    Console.Writeln(PowerComINC.MyDict("IMALF1_A")); //Print 1
    

    根据您的评论:您仍然可以使用由反射填充的字典:

    myDict = typeof(PowerComINC).GetFields(BindingFlags.Static | BindingFlags.NonPublic).ToDictionary(x => x.Name, x => x)
    

    这将为您提供一个字典,其中包含变量名称和一个代表字段的 FieldInfo-instance,然后您可以使用它来获取实际值:

    myDict["IMALF1_A"].GetValue(null);
    

    你甚至可以把它改成Dictionary&lt;string, Func&lt;int&gt;&gt;,这样你就可以直接得到变量值了:

    myDict = typeof(PowerComINC).GetFields(BindingFlags.Static | BindingFlags.NonPublic)
        .ToDictionary(x => x.Name, x => new Func<int>(() => (int) x.GetValue(null));
    

    你现在可以使用这个 - 诚然奇怪 - 语法来调用它:

    var i = myDict["IMALF1_A"]();
    

    【讨论】:

    • 首先谢谢你。这里的问题是。 PowerComINC 是一个包含大约 3000 个变量的庞大类。它已在很多地方用作变量。因此,将其更改为 Dictionary 将涉及更改许多地方的众多变量的现有写入/读取方法。
    【解决方案3】:

    你是怎么做到的? Like so:

    ref int val = ref PowerComINC.GetAssociatedGlobals("IMALF1_A");
    val++;
    Console.WriteLine(PowerComINC.IMALF1_A);
    

    注意ref 在变量声明和赋值前缀中的使用。 (也可以使用ref var val = ...,即隐式确定类型,但ref仍然是必需的)。

    你的方法大概是这样实现的:

    public class PowerComINC
     {
         internal static int IMALF1_A = 0; //INSTRUCTOR MALF ID FOR MISC FUNCTION
         internal static int IMALF2_A = 0; //INSTRUCTOR MALF ID FOR MISC FUNCTION
         internal static int IMFIRE_A = 0; //INSTRUCTOR MALF ID FOR FIRE 
    
         public static ref int GetAssociatedGlobals(string variableName)
         {
             switch (variableName)
             {
                case "IMALF1_A":
                    return ref IMALF1_A;
                case "IMALF2_A":
                    return ref IMALF2_A;
                case "IMFIRE_A":
                    return ref IMFIRE_A;
             }
             throw new ArgumentException(nameof(variableName));
         }
    }
    

    但是,正如 HimBromBeere 所说,以这种方式解决这个问题毫无意义。 switch 查找的性能下降总是超过直接改变像 int 一样小的引用变量的任何性能优势,现在您没有任何字段封装。

    【讨论】:

      猜你喜欢
      • 2013-09-17
      • 2016-04-21
      • 2021-02-13
      • 2012-07-22
      • 1970-01-01
      • 2021-05-01
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多