C#不使用硬编码对继承的类进行随机化
我想要实现的是通过派生类的名称或枚举名生成一个随机派生类。虽然我的代码在这种情况下工作,但如果我决定扩展它,它将需要大量的硬编码,对我来说,这似乎是一个糟糕的解决方案 下面是我的示例代码:(UnitTypes变量动态地包含所有派生类名,因此我觉得它可能很有用,但我可以找出如何使用它。)C#不使用硬编码对继承的类进行随机化,c#,polymorphism,C#,Polymorphism,我想要实现的是通过派生类的名称或枚举名生成一个随机派生类。虽然我的代码在这种情况下工作,但如果我决定扩展它,它将需要大量的硬编码,对我来说,这似乎是一个糟糕的解决方案 下面是我的示例代码:(UnitTypes变量动态地包含所有派生类名,因此我觉得它可能很有用,但我可以找出如何使用它。) 像这样的怎么样。首先创建一个基类(我不知道为什么您将其命名为Unit,我将其命名为BaseAnimal): 这些是非常简单的类,您可以使它们更复杂 最后是一个我认为你想要的测试程序。我从enum的值中获取类的名称
像这样的怎么样。首先创建一个基类(我不知道为什么您将其命名为
Unit
,我将其命名为BaseAnimal):
这些是非常简单的类,您可以使它们更复杂
最后是一个我认为你想要的测试程序。我从enum
的值中获取类的名称,并随意实例化它们
private static readonly Random Random = new Random();
public static void Test()
{
var animalClasses = Enum.GetNames(typeof(EnemiesTypes)).Select(n => n.ToString()).ToArray();
var thisAssembly = Assembly.GetExecutingAssembly().FullName;
for (var i = 0; i < 6; ++i)
{
var className = nameof(AnimalsTest) + "." + animalClasses[Random.Next(0, animalClasses.Length)];
var animal = (BaseAnimal) Activator.CreateInstance(thisAssembly, className).Unwrap();
animal.Attack();
Console.WriteLine($"{animal.GetType().Name} has enemies: {string.Join(", ",animal.Enemies.Select(e=>e.ToString()))}");
Console.WriteLine();
;
}
}
您可以创建一个类型数组(
var types=new[]{typeof(A),typeof(B)/*,…*/};
)甚至一个类型名数组(作为字符串),并使用Activator.CreateInstance
构造实例。您仍然需要创建类。考虑将Name属性作为基类中的抽象吸气剂。然后子类不需要构造函数,但它们确实需要实现getter:public-override-friends-Name=>friends.Dingo代码>不是我的反对票,但这可能是因为您发布了要重构的工作代码,而不是使用了不工作的代码,并且您正在尝试工作。您的问题可能值得发布到。好的,我会记住这一点,以备将来的问题@quaabamm。我很少使用这个网站,也不受互联网两极分化指标的限制(但这是另一个话题)——所以否决票是可以的!。非常感谢你!这正是我想要的,还有更多。单位名称最终是为两个玩家+敌人设计的(但即使是这样,也可能是一个糟糕的选择)。
public class Unit
{
public Enemies Name { get; set; }
public enum Enemies
{
Dingo, Buffalo, Dog
}
public virtual void Attack()
{
//nothing to see here
}
}
class Dingo : Unit
{
public Dingo()
{
Name = Enemies.Dingo;
}
public override void Attack()
{
Console.WriteLine($"{Name} gnaws at your brain");
}
}
namespace AnimalsTest
{
public abstract class BaseAnimal
{
public enum EnemiesTypes
{
Dingo, Buffalo, Dog
}
public abstract IEnumerable<EnemiesTypes> Enemies { get; }
public abstract void Attack();
}
}
class Dingo : BaseAnimal
{
public override IEnumerable<EnemiesTypes> Enemies =>
new List<EnemiesTypes> { EnemiesTypes.Buffalo, EnemiesTypes.Dog };
public override void Attack()
{
Console.WriteLine($"{nameof(Dingo)} Gnaws at your brain");
}
}
class Buffalo : BaseAnimal
{
public override IEnumerable<EnemiesTypes> Enemies =>
new List<EnemiesTypes> { EnemiesTypes.Dog };
public override void Attack()
{
Console.WriteLine($"{nameof(Buffalo)} Runs you down");
}
}
class Dog : BaseAnimal
{
public override IEnumerable<EnemiesTypes> Enemies =>
new List<EnemiesTypes> { EnemiesTypes.Buffalo };
public override void Attack()
{
Console.WriteLine($"{nameof(Dog)} Barks at you");
}
}
private static readonly Random Random = new Random();
public static void Test()
{
var animalClasses = Enum.GetNames(typeof(EnemiesTypes)).Select(n => n.ToString()).ToArray();
var thisAssembly = Assembly.GetExecutingAssembly().FullName;
for (var i = 0; i < 6; ++i)
{
var className = nameof(AnimalsTest) + "." + animalClasses[Random.Next(0, animalClasses.Length)];
var animal = (BaseAnimal) Activator.CreateInstance(thisAssembly, className).Unwrap();
animal.Attack();
Console.WriteLine($"{animal.GetType().Name} has enemies: {string.Join(", ",animal.Enemies.Select(e=>e.ToString()))}");
Console.WriteLine();
;
}
}
Buffalo Runs you down
Buffalo has enemies: Dog
Dog Barks at you
Dog has enemies: Buffalo
Buffalo Runs you down
Buffalo has enemies: Dog
Dog Barks at you
Dog has enemies: Buffalo
Dingo Gnaws at your brain
Dingo has enemies: Buffalo, Dog
Dingo Gnaws at your brain
Dingo has enemies: Buffalo, Dog