c#通过字符串名称获取和设置静态嵌套类中的变量

时间:2018-06-16 11:34:06

标签: c#

所以我想在我的"播放器中存储数据类别"具有静态类的类,以便它们是命名变量并且可以按名称调用。我最近找到了一个解决方案,用于通过字符串名称调用类中的变量来获取并在此处设置它们:C# setting/getting the class properties by string name我试图通过使用" Type.GetType(pattern)&来通过字符串调用静态类#34;:Get class by string value

我试图修改对象以便用字符串调用静态类,但我遗漏了一些东西,因为get和set根本不起作用:

public class Player
{

    //categories of variables within static classes
    public static class Status { public static int health = 10, stamina = 10, mana = 10; };
    public static class Immunity { public static bool fire = false, water = false, giantEnemyCrab = true; };
    //paralell arrays 
    public string[] namelistStatus = { "health", "stamina", "mana" };
    public string[] namelistImmunity = { "fire", "water", "giantEnemyCrab" };


    //get and set Variables from nested classes
    //('classname' is the name of the class,'propertyName' is the name of the variable)
    public object this[string className, string propertyName]
    {
        //indirectly calls variables within static classes entirely via string
        get
        {

            //i think the problem originates from "Type.GetType(className)" not being the correct way to call the static class by their string name
            Type myType = Type.GetType(className);
            PropertyInfo myPropInfo = myType.GetProperty(propertyName);
            return myPropInfo.GetValue(this, null);
        }
        set
        {

            Type myType = Type.GetType(className);
            PropertyInfo myPropInfo = myType.GetProperty(propertyName);
            myPropInfo.SetValue(this, value, null);
        }
    }
    //display variables
    public void DisplayPlayerStatus()
    {
        for (int i = 0; i < namelistStatus.Length; i++)
        {
            Console.WriteLine(namelistStatus[i]+":"+this["Status", namelistStatus[i]]);
        }
        for (int i = 0; i < namelistStatus.Length; i++)
        {
            if (Convert.ToBoolean(this["Immunity", namelistStatus[i]]))
            {
                Console.WriteLine(namelistStatus[i] + " Immunity");
            }
        }
    }

}

这是我试图用嵌套静态类组织的Player类的简化,还有一些函数用于设置状态和免疫类中的变量但是这里我只做了一个示例函数为了获得&#39;嵌套的静态类变量通过字符串,但设置&#39;也不起作用。 任何有关我如何能够做到这一点的建议都将非常感激。

1 个答案:

答案 0 :(得分:0)

<强>问题:

  • static inner classes只是你nested Types课程内的Player - 而不是你的播放器课程的properties

  • 您的静态类中的properties实际上是Field s。

  • 您在Immunities

  • Player.DisplayPlayerStatus()使用了错误的名单

你可以(但你真的不应该重新考虑你的设计)来解决这个问题

public class Player
{
    public string[] namelistImmunity = { "fire", "water", "giantEnemyCrab" };
    public string[] namelistStatus = { "health", "stamina", "mana" };

    public object this[string className, string propertyName]
    {
        //indirectly calls variables within static classes entirely via string
        get
        {
            var innerClass = GetType().GetNestedType(className);
            var myFieldInfo = innerClass?.GetField(propertyName);
            return myFieldInfo.GetValue(null);
        }
        set
        {
            var innerClass = GetType().GetNestedType(className);
            var myFieldInfo = innerClass?.GetField(propertyName);
            myFieldInfo?.SetValue(null, value);
        }
    }

    public void DisplayPlayerStatus()
    {
        // why for and indexing - foreach is far easier
        foreach (var s in namelistStatus)
            Console.WriteLine(s + ":" + this["Status", s]);

        // you used the wrong list of names here 
        foreach (var n in namelistImmunity) 
            if (Convert.ToBoolean(this["Immunity", n]))
                Console.WriteLine(n + " Immunity");
    }

    public static class Immunity 
    {
        // these are fields 
        public static bool fire = false, 
                           water = false, 
                           giantEnemyCrab = true; 
    };

    public static class Status 
    {
        // fields as well 
        public static int health = 10, 
                      stamina = 10, 
                      mana = 10; 
    };
}

经过测试:

using System; 

internal class Program
{
    public static void Main(string[] args)
    {
        Player p = new Player();
        p.DisplayPlayerStatus();

        Console.WriteLine();

        p["Status", "health"] = 200;
        p.DisplayPlayerStatus();

        Console.ReadLine();
    }

    // the fixed stuff goes here
}

输出:

health:10
stamina:10
mana:10
giantEnemyCrab Immunity

health:200
stamina:10
mana:10
giantEnemyCrab Immunity

您的课程目前非常紧张,如果您在统计信息中添加psyonicPower,则需要修改Player,修改Player.Status,修改Player.namelistStatus

你可以通过反射以类似的方式自动发现静态类字段名,就像你访问字段值并摆脱你的namelistXXXX一样 - 但是,设计仍然很糟糕。