【问题标题】:C# - How to access a static class variable given only the class type?C# - 如何访问仅给定类类型的静态类变量?
【发布时间】:2012-05-31 16:52:54
【问题描述】:

这是我第一次在 Stack Overflow 上发帖,希望我所做的一切都是正确的,你们可以提供帮助。

我想知道在 C# 中是否有一种方法可以访问属于某个类的静态变量,前提是仅给出类的类型。例如:

public class Foo
{
    public static int bar = 0;
}

public class Main
{
    public void myFunc(Type givenType)
    {
        int tempInt = ??? // Get the value of the variable "bar" from "Foo"
        Debug.WriteLine("Bar is currently :" + tempInt);
    }
}

// I didn't run this code through a compiler, but its simple enough
// that hopefully you should get the idea...

很难描述需要了解这一点的背景,但我正在使用 XNA 制作游戏,并且我正在尝试使用引用计数来降低设计的复杂性。我在游戏中有物体和可以应用效果的道具(留在物体上)。能量提升可能会消失,但它们的影响仍然会留在对象上,我需要跟踪能量提升的任何影响是否仍然存在于对象上(因此,引用计数)。我计划用一个静态整数创建一个“PowerUpEffect”类(针对每种类型的加电),以保存仍然受它影响的对象的数量,但是游戏其余部分的设计不能很好地传递 PowerUpEffect一直到对象调用 PowerUpEffect 类的方法。

我希望只传递 PowerUpEffect 的类型(使用类似“typeOf()”之类的东西)并使用该类型来引用属于这些类型的静态变量,但我不知道该怎么做,或者它是否可能.

我很乐意找到不直接回答这些问题但以简单而优雅的设计解决问题的变通方法。 =)

帮助! (谢谢!)

【问题讨论】:

  • 反射会在这里得到你想要的,但是不要像这样使用反射,你可能想考虑使用单例模式。

标签: c# xna reference-counting


【解决方案1】:

如果你只有类型句柄,你可以这样做:

var prop = givenType.GetProperty("bar");
var value = prop.GetValue(null);

【讨论】:

  • 这正是我想做的! (“var”除外)完美,谢谢
【解决方案2】:

我会改用Dictionary,这可能是将一组值映射到另一组值的最简洁方式。如果您将int 值与Types 关联,请执行以下操作:

public static readonly Dictionary<Type, int> sTypeValues =
   new Dictionary<Type, int>
{
   { typeof(Type1), 5 },
   { typeof(Type2), 10 },
   { typeof(Type3), 2 },
   { typeof(Type4), 3 },
   { typeof(Type5), -7 }
};

然后你的函数变成:

public void myFunc(Type givenType)
{
    int tempInt = sTypeValues[givenType];
    Debug.WriteLine("Bar is currently :" + tempInt);
}

【讨论】:

  • 虽然这不是我想要的答案,但在对代码进行了进一步审查之后,这就是我要使用的解决方案类型。感谢您的帮助
【解决方案3】:

int tempInt = (int) givenType.GetField("bar").GetValue(null);

【讨论】:

  • 完美,这就是我想做的。谢谢
【解决方案4】:

好的,所以你有一个通电集合,并且你希望有一个与每个通电相关联的整数。您可以拥有一个静态集合,而不是拥有很多类,每个类都有一个静态整数。

public static class MyPowerupInfo
{
  public static Dictionary<PowerUp, int> PowerUps {get; private set;}
  static MyPowerupInfo
  {
    PowerUps = new Dictionary<PowerUp, int>();
    PowerUps.Add(*some power up object goes here*, 0);
    //TODO add other power ups
  }
}

然后要使用它,您可以执行以下操作:

int powerupCount = MyPowerupInfo.PowerUps[wickedAwesomePowerup];

或:

public static void IncrementPowerup(Powerup powerup)
{
  MyPowerupInfo.PowerUps[powerup] = MyPowerupInfo.PowerUps[powerup]+1;
}

【讨论】:

  • 信不信由你,虽然这不是我想要的确切答案,但经过进一步审查,这就是我要使用的解决方案类型。谢谢!
【解决方案5】:

如果我让你正确,这可能会给你一些想法:

使用系统; 使用 System.Reflection;

public class RStatic
{
    private static int SomeNumber {get; set;}
    public static object SomeReference {get; set;}
    static RStatic()
    {
        SomeReference = new object();
        Console.WriteLine(SomeReference.GetHashCode());
    }
}

public class Program
{
    public static void Main()
    {
        var rs = new RStatic();
        var pi = rs.GetType().GetProperty("SomeReference",  BindingFlags.Static | BindingFlags.Public); // i have used GetProperty in my case

        Console.WriteLine(pi.GetValue(rs, null).GetHashCode());


    }
}

【讨论】:

    【解决方案6】:

    您是否假设您尝试访问的字段名称(例如,对于“foo”类,字段“bar”)是否是基于 Type 参数的不同字段?

    如果字段的名称是基于有限数量的允许类型已知的,您应该能够使用 switch 语句来确定它。例如:

    public class Foo
    {
        public static int bar = 0;
    }
    
    public class Baz
    {
        public static int bing = 0;
    }
    
    public class Main
    {
        public void myFunc(Type givenType)
        {
            switch (givenType.ToString())
            {
                case "Foo":
                    Debug.WriteLine("Bar is currently :" + Foo.bar);
                    break;
                case "Baz":
                    Debug.WriteLine("Bing is currently :" + Baz.bing);
                    break;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-29
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多