如何以可以从 C# 中的其他方法访问的方式存储随机 class 变量?
How to store random class variable in way that can be accessed from other methods in C#?
我需要得到一个随机的 class,存储到一个 "global class" 变量中(这样我就可以用其他方法访问它),但是我找不到任何好的方法来做到这一点,怎么办?我一直在尝试使用对象变量...我是从 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
}
}
我该如何解决这个问题?谢谢
编译器将一个变量类型化为对象,编译器将验证所有实例成员是否有效。另一个变量类型为动态,所有实例成员将被编译器忽略并在执行时由 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
}
}
解决方案一:
在 doActionWithChoosedMan() 方法中,您直接使用了 chosenMan,但这不是正确的做法。
在使用它之前你必须检查 chosenMan 的类型
通过
if(chosenMan.GetType() == typeof(man1)){
man1 man11= new man1();
Console.WriteLine(man11.val); //No Error
}if(chosenMan.GetType() == typeof(man2)){
man1 man22= new man1();
Console.WriteLine(man22.val); //No Error
}if(chosenMan.GetType() == typeof(man3)){
man1 man33= new man1();
Console.WriteLine(man33.val); //No Error
}
同样,您必须检查所有对象,然后创建位于 "man1" 的主要 class 的对象,然后您将能够访问 "val"。
方案二:你可以让chosenMan动态化。
虽然@programtreasures 发布了一个很好的即时解决方案,但您需要考虑 C# 是一种强类型语言。这意味着,与 python 和 javascript 不同,您不能尝试随机访问对象上未声明的属性和方法。
请注意,在您演示的情况下,您的 3 classes 没有区别。它们应该只是类型 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
基础 class 以仅容纳您需要的 属性,然后将其余内容堆叠在上面。这取决于默认初始化是否在 classes 之间共享,以及是否有任何其他共同点需要实现。
我需要得到一个随机的 class,存储到一个 "global class" 变量中(这样我就可以用其他方法访问它),但是我找不到任何好的方法来做到这一点,怎么办?我一直在尝试使用对象变量...我是从 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
}
}
我该如何解决这个问题?谢谢
编译器将一个变量类型化为对象,编译器将验证所有实例成员是否有效。另一个变量类型为动态,所有实例成员将被编译器忽略并在执行时由 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
}
}
解决方案一: 在 doActionWithChoosedMan() 方法中,您直接使用了 chosenMan,但这不是正确的做法。
在使用它之前你必须检查 chosenMan 的类型 通过
if(chosenMan.GetType() == typeof(man1)){
man1 man11= new man1();
Console.WriteLine(man11.val); //No Error
}if(chosenMan.GetType() == typeof(man2)){
man1 man22= new man1();
Console.WriteLine(man22.val); //No Error
}if(chosenMan.GetType() == typeof(man3)){
man1 man33= new man1();
Console.WriteLine(man33.val); //No Error
}
同样,您必须检查所有对象,然后创建位于 "man1" 的主要 class 的对象,然后您将能够访问 "val"。
方案二:你可以让chosenMan动态化。
虽然@programtreasures 发布了一个很好的即时解决方案,但您需要考虑 C# 是一种强类型语言。这意味着,与 python 和 javascript 不同,您不能尝试随机访问对象上未声明的属性和方法。
请注意,在您演示的情况下,您的 3 classes 没有区别。它们应该只是类型 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
基础 class 以仅容纳您需要的 属性,然后将其余内容堆叠在上面。这取决于默认初始化是否在 classes 之间共享,以及是否有任何其他共同点需要实现。