如何以可以从C#中的其他方法访问的方式存储随机类变量?

时间:2018-01-02 03:40:43

标签: c# arrays class oop typed

我需要一个随机的课程,存入一个"全球课程"变量(所以我可以在其他方法中访问它),但我找不到任何好的方法来做,我一直试图做的是使用对象变量...我来自python到c#,所以对象变量的属性对我来说看起来很神秘......我一直在寻找如何使它工作,但是如果没有一堆if语句我找不到合适的方法...

//There might not be all the necessary namespaces to run this code
using UnityEngine; //where the random.range() came from

public class man1 //Initialization of the first class
{
    public int val = 1;
}

public class man2 //Initialization of the second class
{
    public int val = 2;
}

public class man3 //Initialization of the third class
{
    public int val = 3;
}

public class allMan
{ //Where all classes 'merge'

    private object chosenMan; //Where the chosen it's going to be stored

    public allMan() //Constructor
    {
        //Have all man in one array to easily get the chosen from index
        object[] men = new object[] { new man1(), new man2(), new man3() }; 
        var choice = Random.range(0, men.Length); //Randomly get the index
        chosenMan = men[choice]; // Atribute the chosen class
    }
    public void doActionWithChoosedMan()
    {
        Console.WriteLine(chosenMan.val); //ERROR
    }
}

我该如何处理这个问题?感谢。

3 个答案:

答案 0 :(得分:3)

虽然@programtreasures发布了一个很好的即时解决方案,但您需要考虑C#是一种强类型语言。这意味着,与python和javascript不同,您无法尝试随机访问对象上未声明的属性和方法。

请注意,在您演示过的情况下,您的3个班级没有任何区别。它们应该只是Man类型的实例,就像这样

class Man 
{
 public int Val { get; set; } // try to use properties to hold externally accessible values
}

public class AllMan // c# uses Pascal casing
{ //Where all classes 'merge'

    private Man chosenMan; //Where the chosen it's going to be stored

    public AllMan() //Constructor
    {
        //Have all man in one array to easily get the chosen from index
        var men = new Man[] { new Man() { Val = 1 }, new Man() { Val = 2 }, new Man() { Val = 3 } }; 
        var choice = Random.range(0, men.Length); //Randomly get the index
        chosenMan = men[choice]; // Atribute the chosen class
    }

    public void DoActionWithChoosedMan()
    {
        Console.WriteLine(chosenMan.Val);
    }
}

对于要求您在类型上有差异的内容,您可以声明一个接口,例如

interface IMan
{
int Val {get;}
}

然后让你的不同类型实现这个:

class Man1 : IMan
{
public int Val {get;} = 1;
public string SomethingElse {get;set;}
}

class Man2 : IMan
{
public int Val {get;} = 2;
public boolean AmICool {get;set;}
}

然后您可以运行上述代码,但将chosenMan字段的类型更改为IMan

此外,您可能还希望实现一个abstract基类来保存您需要的属性,然后将其余内容堆叠在顶部。这取决于是否跨类共享默认初始化以及是否还有其他需要实现的常见初始值。

答案 1 :(得分:2)

编译器将一个变量作为对象输入,并且编译器将验证所有实例成员是否有效。另一个变量被输入为dynamic,编译器将忽略所有实例成员,并在执行时由DLR调用。

您可以使用dynamic代替object

 public class allMan
   { 
    //Where all classes 'merge'

    private dynamic chosenMan; //Where the chosen it's going to be stored

    public allMan() //Constructor
    {
        //Have all man in one array to easily get the chosen from index
        object[] men = new object[] { new man1(), new man2(), new man3() };
        var choice = Random.range(0, men.Length); //Randomly get the index
        chosenMan = men[choice]; // Atribute the chosen class
    }
    public void doActionWithChoosedMan()
    {
        Console.WriteLine(chosenMan.val); //ERROR
    }
}

答案 2 :(得分:0)

解决方案1: 在doActionWithChoosedMan()方法中,您直接使用selectedMan,但这不是正确的做法。

在使用它之前,你必须检查所选人的类型 通过

python3 -m pip install -U --force-reinstall pip
python -m pip install -U --force-reinstall pip

你必须检查所有对象,然后创建主类的对象,这里是" man1"然后你就可以访问" val"。

解决方案2:您可以让selectedMan动态化。