多态性、继承和泛型C#:无法将子类强制转换为超类型

本文关键字:子类 转换 类型 超类 继承 泛型 多态性 | 更新日期: 2023-09-27 18:00:12

我在c#中遇到了抽象类和泛型的问题(我通常用Java编码):这是我想使用的代码:

public interface InterfaceResult {...}
public abstract class Result : InterfaceResult {...}   
public class ResultA : Result {...}
public class ResultB : Result {...}
public interface InterfaceKing { InterfaceResult function();}
public abstract class King : InterfaceKing {
  public abstract Result function();
}
public class KingA : King {
  public override ResultA function(){...}
}
public class KingB : King {
  public override ResultB function(){...}
}

但这不起作用:Visual Studio希望KingA和KingB使用function()返回Result的实例。如果我使用"new"而不是override,VS说我没有实现所需的方法(我需要使用override)。

所以我尝试了通用,但它并没有更好的

public abstract class Result    {    }
public class ResultA : Result    {    }
public class ResultB : Result    {    }
public interface IKing<T>    {T function();    }
public abstract class King<Result> : IKing<Result>
{
    public abstract Result function();
    public static implicit operator King<Result>(KingB v)
    {
        return v; // generate StackOverflow Exception
    }
    public static implicit operator King<Result>(KingA v)
    {
        throw new NotImplementedException();
    }
}
public class KingA : King<ResultA>
{
    public override ResultA Get()
    {
        return new ResultA();
    }
}
public class KingB : King<ResultB>
{
    public override ResultB Get()
    {
        return new ResultB();
    }
}
public class Test
{
    King<Result> a = new KingA(); // allowed by  public static implicit operator King<Result>(KingA v)
    King<Result> b = new KingB(); // allowed by  public static implicit operator King<Result>(KingB v)
    KingA ka = new KingA();
    List<King<Result>> lista = new List<King<Result>>();
    public void test()
    {
        lista.Add(ka);
    }        
}

我该怎么做?我找不到任何解决方案,也找不到什么好的或完整的例子。

多态性、继承和泛型C#:无法将子类强制转换为超类型

从"完整接口"到"无接口"(因为没有更好的术语)所有这些都有效(this Main运行良好)

static void Main ()
{
    King a = new KingA ();
    King b = new KingB ();
    KingA ka = new KingA ();
    List<King> list = new List<King> ();
    list.Add (a);
    list.Add (b);
    list.Add (ka);
}

"完整界面"

    public interface InterfaceResult { }
    public abstract class Result : InterfaceResult { }
    public class ResultA : Result { }
    public class ResultB : Result { }
    public interface InterfaceKing { InterfaceResult Function (); }
    public abstract class King : InterfaceKing
    {
        public abstract InterfaceResult Function ();
    }
    public class KingA : King
    {
        public override InterfaceResult Function () => new ResultA ();
    }
    public class KingB : King
    {
        public override InterfaceResult Function () => new ResultA ();
    }

"混合(较少接口)"

    public abstract class Result { }
    public class ResultA : Result { }
    public class ResultB : Result { }
    public interface IKing { Result Function (); }
    public abstract class King : IKing
    {
        public abstract Result Function ();
    }
    public class KingA : King
    {
        public override Result Function () => new ResultA ();
    }
    public class KingB : King
    {
        public override Result Function () => new ResultB ();
        {
            return new ResultB ();
        }
    }

"无接口"

    public abstract class Result { }
    public class ResultA : Result { }
    public class ResultB : Result { }
    public abstract class King
    {
        public abstract Result Function ();
    }
    public class KingA : King
    {
        public override Result Function () => new ResultA ();
    }
    public class KingB : King
    {
        public override Result Function () => new ResultB ();
    }

使用协方差

看到了。这里是网络小提琴手。阅读更多关于协方差和反方差的信息

public abstract class Result { }
public class ResultA : Result { }
public class ResultB : Result { }
public interface IKing<out T> where T : Result {}
public abstract class King<T> : IKing<T> where T : Result
{
    public abstract T Get();
}
public class KingA : King<ResultA>
{
    public override ResultA Get()
    {
        return new ResultA();
    }
}
public class KingB : King<ResultB>
{
    public override ResultB Get()
    {
        return new ResultB();
    }
}
public class TestClass
{
    King<ResultA> a = new KingA(); // allowed by  public static implicit operator King<Result>(KingA v)
    King<ResultB> b = new KingB(); // allowed by  public static implicit operator King<Result>(KingB v)
    KingA ka = new KingA();
    List<IKing<Result>> lista = new List<IKing<Result>>();
    public void Test()
    {
        lista.Add(ka);
    }        
}