Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何以可以从C#中的其他方法访问的方式存储随机类变量?_C#_Arrays_Class_Oop_Typed - Fatal编程技术网

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

如何以可以从C#中的其他方法访问的方式存储随机类变量?,c#,arrays,class,oop,typed,C#,Arrays,Class,Oop,Typed,我需要得到一个随机类,存储到一个“全局类”变量中(这样我就可以用其他方法访问它),但我找不到任何好的方法来实现它,我一直在尝试的是使用对象变量。。。我从python到c#,所以对象变量的属性对我来说有点神秘。。。我一直在寻找如何使它工作,但我找不到一个适当的方法来做它没有一堆如果语句 //There might not be all the necessary namespaces to run this code using UnityEngine; //where the random.ra

我需要得到一个随机类,存储到一个“全局类”变量中(这样我就可以用其他方法访问它),但我找不到任何好的方法来实现它,我一直在尝试的是使用对象变量。。。我从python到c#,所以对象变量的属性对我来说有点神秘。。。我一直在寻找如何使它工作,但我找不到一个适当的方法来做它没有一堆如果语句

//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
    }
}

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

编译器将一个变量类型化为object,编译器将验证所有实例成员是否有效。另一个变量类型为动态变量,编译器将忽略所有实例成员,并在执行时由DLR调用

您可以使用
动态
而不是
对象

 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
    }
}

编译器将一个变量类型化为object,编译器将验证所有实例成员是否有效。另一个变量类型为动态变量,编译器将忽略所有实例成员,并在执行时由DLR调用

您可以使用
动态
而不是
对象

 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
    }
}

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

在使用它之前,你必须检查chosenMan的类型 借

同样,您必须检查所有对象,然后创建主类的对象,在这里是“man1”,然后您将能够访问“val”


解决方案2:您可以使chosenMan变得动态。

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

在使用它之前,你必须检查chosenMan的类型 借

同样,您必须检查所有对象,然后创建主类的对象,在这里是“man1”,然后您将能够访问“val”


<强>解决方案2:< /强>可使CHOSENMAN动态。

而@程序库发布一个好的即时解决方案时,您需要考虑C是强类型语言。这意味着,与python和javascript不同,您不能尝试随机访问对象上未声明的属性和方法

请注意,在您演示的案例中,三个类之间没有差异。它们应该只是类型
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


此外,您可能还希望实现一个
抽象
基类,以便只保存所需的属性,然后将其余内容堆叠在上面。这取决于默认初始化是否跨类共享,以及是否还有其他常见的需要实现的问题。

< P>而@程序宝发布了一个很好的即时解决方案时,您需要考虑C是一种强类型语言。这意味着,与python和javascript不同,您不能尝试随机访问对象上未声明的属性和方法

请注意,在您演示的案例中,三个类之间没有差异。它们应该只是类型
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


此外,您可能还希望实现一个
抽象
基类,以便只保存所需的属性,然后将其余内容堆叠在上面。这取决于默认初始化是否在类之间共享,以及是否有其他需要实现的通用项。

类man1、man2和man3没有提供足够的详细信息来说明为什么要这样做。你介意用另一个例子来说明你为什么要这样做吗?你可能只是有一个很糟糕的例子。但是如果所有类都共享公共特征,那么创建一个基类来表示公共特征,并使所有类都派生自公共基类。然后将选择的对象作为基类类型;它是一个(伪)随机数生成器,所以为什么你不能在需要它们的地方创建你喜欢的任意数量的随机数呢?输出不会改变类man1、man2和man3没有提供足够的详细信息说明您为什么要这样做。你介意用另一个例子来说明你为什么要这样做吗?你可能只是有一个很糟糕的例子。但是如果所有类都共享公共特征,那么创建一个基类来表示公共特征,并使所有类都派生自公共基类。然后将选择的对象作为基类类型;它是一个(伪)随机数生成器,所以为什么你不能在需要它们的地方创建你喜欢的任意数量的随机数呢?产量不会下降change@OP如果采用这种方法,请注意,这通常不是一种很好的C#实践,为什么这样做不好?使用dynamic也会在运行时增加很少的工作,并且在编译时也不会获得类型检查的优势。如果可以使用继承/接口(根据Zaitsman的回答)来完成,那么为什么要使用dynamic?@KaiqueSantos dynamic不好