【问题标题】:Cannot convert from a type to other type无法从一种类型转换为其他类型
【发布时间】:2026-01-14 13:25:02
【问题描述】:

我在 OOP 中练习,我创建了一个简单的控制台应用程序,其中我有 3 个派系,每个派系都必须有自己的军队,每个不同的军队都可以包含某些单位。

我使用了接口和继承,但是我在泛型转换中遇到了一些问题。我不知道如何以正确的方式解决这个问题,请帮助我。

这里是代码。

这是我的ArmyUnits 实现。

public abstract class Unit<T> : IUnit<T> where T : Faction {
    public string UnitName { get; set; }
    public IFaction Nation { get; set; }

    public Unit(string name) {
        UnitName = name;
    }

    public virtual void PrintUnitInfo() {
        Console.WriteLine($"UnitName: {UnitName}\nNation: {Nation}\n");
    }
}

public interface IUnit<T> where T : IFaction {
    string UnitName { get; set; }
    IFaction Nation { get; set; }

    void PrintUnitInfo();
}

public class Army<T> where T : IFaction {
    private List<IUnit<T>> units = new List<IUnit<T>>();

    public void Recruit(IUnit<T> unit) {
        units.Add(unit);
    }

    public void PrintFactionName() {
        Console.WriteLine(nameof(IFaction));
    }

}

这是Faction 的实现。

public abstract class Faction : IFaction {
    public string Name { get; }
    public int Minerals { get; set; }
    public Army<Faction> Army { get; set; }

    public Faction(string name, Army<Faction> army) {
        Name = name;
        Minerals = 100;
        Army = army;
    }

    public virtual void Greetings() {
        Console.WriteLine("Printing FucntionInfo from BaseFaction");
    }

    public virtual void PrintUnitsInfo() {
        Console.WriteLine("Printing UnitsInfo from BaseFaction");
    }

}

public interface IFaction {

    string Name { get; }
    Army<Faction> Army { get; set; }
    int Minerals { get; set; }

    void Greetings();
    void PrintUnitsInfo();

}

最后这里是编译器显示错误的用法:

Cannot convert from 'Army&lt;Zerg&gt;' to 'Army&lt;Faction&gt;".

public static void Main(string[] args) {

        Faction zerg = new Zerg("Zerg", new Army<Zerg>());


        zerg.Army.PrintFactionName();

        Console.ReadKey();

    }

}

public class Zerg : Faction {

    public Zerg(string name, Army<Faction> army) : base(name, army) { }

}

抱歉,如果问题看起来非常大且令人困惑,但我无法通过其他方式明确我的问题。

【问题讨论】:

  • 拜托,主要的邮政编码,而不是图像!您永远不会在IUnit&lt;T&gt;Unit&lt;T&gt; 中使用T,也不会在您提供的其余代码中使用。所以用泛型也没用……
  • 但是如何在没有泛型的情况下指定某个军队的派系呢?好的,我会编辑它
  • 尝试使用 UML 或仅使用纸和铅笔绘制矩形和线条来绘制层次结构图。你会看到你设计的缺陷。
  • 我试过了,但每次尝试都无法达到我想要的效果

标签: c# .net generics


【解决方案1】:

您从不在IUnit&lt;T&gt;Unit&lt;T&gt; 中使用T,也不在您提供的其他代码中使用。所以用泛型是没用的……

所以你可以简单地写:

static void Test()
{
  Faction zerg = new Zerg("Zerg", new Army());
  zerg.Army.Recruit(new Zealot("Zealot"));
  Console.ReadKey();
}

public interface IUnit
{
  string UnitName { get; set; }
  IFaction Nation { get; set; }

  void PrintUnitInfo();
}

abstract public class Unit : IUnit
{
  public string UnitName { get; set; }
  public IFaction Nation { get; set; }

  public Unit(string name)
  {
    UnitName = name;
  }

  public virtual void PrintUnitInfo()
  {
    Console.WriteLine($"UnitName: {UnitName}\nNation: {Nation}\n");
  }
}

public interface IFaction
{
  Army Army { get; set; }
  string Name { get; }
  int Minerals { get; set; }

  void Greetings();
  void PrintUnitsInfo();
}

public abstract class Faction : IFaction
{
  public string Name { get; }
  public int Minerals { get; set; }
  public Army Army { get; set; }

  public Faction(string name, Army army)
  {
    Name = name;
    Minerals = 100;
    Army = army;
  }

  public virtual void Greetings()
  {
    Console.WriteLine("Printing FucntionInfo from BaseFaction");
  }

  public virtual void PrintUnitsInfo()
  {
    Console.WriteLine("Printing UnitsInfo from BaseFaction");
  }
}

public class Army
{
  private List<IUnit> units = new List<IUnit>();

  public void Recruit(IUnit unit)
  {
    units.Add(unit);
  }

  public void PrintFactionName()
  {
    Console.WriteLine(nameof(IFaction));
  }
}

public class Zerg : Faction
{
  public Zerg(string name, Army army) : base(name, army) { }
}

public class Zealot : Unit
{
  public Zealot(string name) : base(name) { }
}

现在,如果您想使用泛型做一些我不理解的事情,您可以通过使用纸、铅笔和带线条的矩形绘制简单的绘图来改进您的设计,或者您可以使用 UML。

UML Tutorial

还有一个问题要问你:为什么要使用接口?

要回答这个问题,请问:我为定义接口而编写的代码,我用它来做什么?

泛型也是如此。

What is the difference between an interface and a class, and why I should use an interface when I can implement the methods directly in the class?

C# Generics Level 1
C# Generics Level 2
Generics in .NET

【讨论】:

  • 让我把事情说得更清楚些。在这段代码中一切都很好,在我上面发布的代码中也是如此,但是有一个问题。例如,如果我创建了作为 Prottos 单位的 Zealot 并且我有 Zerg 对象,那么我可以在 zergs 军队中添加 zealot,我唯一想做的就是当我编写 zerg.army.recruit(new Zealot()) 编译器应该返回当时一个错误并限制我这样做
  • *者是战斗机单位,必须列入陆军名单
  • 你可以。答案已更新。试着用纸和铅笔画一幅画,画出矩形和线条来连接它们。
  • 不使用UML,可以这么简单:paper-and-pencil-design。我强烈推荐学习 UML。
最近更新 更多