C# 在非泛型类上重写泛型方法

C# 在非泛型类上重写泛型方法,c#,generics,overriding,generic-method,C#,Generics,Overriding,Generic Method,我知道在使用泛型类时如何实现我的目标。但要理解为什么非泛型类中允许泛型方法的语法(声明为虚拟或抽象),我似乎无法确定 第一段代码显示了一个简单的示例,使用泛型类创建一个抽象方法,该方法返回的接口比基类中约束的接口更具体 public interface ISeries { string Name { get; set; } string Color { get; set; } } public interface ITimeSeries<TY> : ISeries {

我知道在使用泛型类时如何实现我的目标。但要理解为什么非泛型类中允许泛型方法的语法(声明为虚拟或抽象),我似乎无法确定

第一段代码显示了一个简单的示例,使用泛型类创建一个抽象方法,该方法返回的接口比基类中约束的接口更具体

public interface ISeries
{
    string Name { get; set; }
    string Color { get; set; }
}
public interface ITimeSeries<TY> : ISeries
{
    double[] XValues { get; set; }
    TY[] YValues { get; set; }
}

public interface IPhasorSeries : ISeries
{
    double Magnitude { get; }
    double Angle { get; }
}
public class PhasorSeries : IPhasorSeries
{
    public string Name { get; set; }
    public string Color { get; set; }
    public double Magnitude { get; set; }
    public double Angle { get; set; }
}
public class Series<T> : ITimeSeries<T>
{
    public string Name { get; set; }
    public string Color { get; set; }
    public double[] XValues { get; set; }
    public T[] YValues { get; set; }
}
public abstract class Chart<T> where T : ISeries
{
    public abstract T GetSeries();
}

public class AnalogChart : Chart<ISeries>
{
    public override ISeries GetSeries()
    {
        return new Series<float>();
    }
}

public class PhasorChart : Chart<IPhasorSeries>
{
    public override IPhasorSeries GetSeries()
    {
        return new PhasorSeries();
    }
}
公共接口ISeries
{
字符串名称{get;set;}
字符串颜色{get;set;}
}
公共接口系统:ISeries
{
double[]XValues{get;set;}
TY[]YValues{get;set;}
}
公共接口IPhasorSeries:ISeries
{
双幅{get;}
双角度{get;}
}
公共类相系列:IPhasorSeries
{
公共字符串名称{get;set;}
公共字符串颜色{get;set;}
公共双量级{get;set;}
公共双角度{get;set;}
}
公共类系列:ITimeSeries
{
公共字符串名称{get;set;}
公共字符串颜色{get;set;}
public double[]XValues{get;set;}
公共T[]y值{get;set;}
}
公共抽象类图,其中T:ISeries
{
公共摘要T GetSeries();
}
公共类图表:图表
{
公共覆盖ISeries GetSeries()
{
返回新系列();
}
}
公共类PhasorChart:图表
{
公共覆盖IPhasorSeries GetSeries()
{
返回新的相序列();
}
}
现在,如果从图表类中删除泛型类型,但保留带有ISeries约束的泛型方法,则会出现以下错误

public abstract class Chart
{
    public abstract T GetSeries<T>() where T : ISeries;
}

public class AnalogChart : Chart
{
    public override T GetSeries<T>()
    {
        // ERROR:
        // Cannot implicitly convert type Test.Series<float> to 'T'
        // Cannot convert expression type Test.Series<float> to return type 'T'
        return new Series<float>();
    }
}

public class PhasorChart : Chart
{
    public override T GetSeries<T>()
    {
        // ERROR:
        // Cannot implicitly convert type Test.PhasorSeries to 'T'
        // Cannot convert expression type Test.PhasorSeries to return type 'T'
        return new PhasorSeries();
    }
}
公共抽象类图
{
公共摘要T GetSeries(),其中T:ISeries;
}
公共类图表:图表
{
公共覆盖GetSeries()
{
//错误:
//无法将类型测试.Series隐式转换为“T”
//无法将表达式类型Test.Series转换为返回类型“T”
返回新系列();
}
}
公共类PhasorChart:图表
{
公共覆盖GetSeries()
{
//错误:
//无法将type Test.PhasorSeries隐式转换为“T”
//无法将表达式类型Test.PhasorSeries转换为返回类型“T”
返回新的相序列();
}
}
似乎我不完全理解在非泛型类中实现泛型方法时发生了什么。当使用泛型类时——存在多个类定义。当您只有一个泛型方法时,这意味着什么?实际上有多种方法吗?或者它只是调用了相同的方法

如果抽象关键字和虚拟关键字基本上不支持这一点,我希望在创建抽象泛型方法时会出现错误。如果不能使用此处的语法来避免在其他代码中强制转换,那么如何正确使用抽象泛型方法。(我甚至不能将t转换为一个ISeries——看起来约束在子类中丢失了,好像它不知道t必须是一个ISeries)


请注意,此处问题的目的是了解如何解决此问题或提出不同的“解决方案”。

当您的返回类型为
T
时,您必须返回
T
,无论
T
是什么。不能返回硬编码类型的对象并希望它是t

假设您执行以下代码

Series<int> intSeries = angloChart.GetSeries<Series<int>>();
Series intSeries=angloChart.GetSeries();

根据
GetSeries
的签名,这将是有效的代码,但是,您编写的方法如果具有可比性,将
Series
放入
Series
类型的变量中,这就是
返回新序列()的原因T

的方法中不允许使用code>。使用泛型方法时,这意味着您不知道该
T
参数的具体类型

那么,您如何确定它是一个
系列

是什么阻止我这样调用此方法:

var ac = new AnalogChart();
Series<int> series = ac.GetSeries<Series<int>>();

为了达到预期的效果,我意识到我可以使用显式接口实现并避免同时使用泛型

public interface IChart
{
    ISeries GetSeries();
}
public abtract class Chart : IChart
{
    public virtual ISeries GetSeries()
    {
        throw new NotImplementedException();
    }
}

public class AnalogChart : Chart, IChart
{
    public new ITimeSeries<float> GetSeries()
    {
        return new Series<float>();
    }

    ISeries IChart.GetSeries()
    {
        return GetSeries();
    }
}

public class PhasorChart : Chart, IChart
{
    public new IPhasorSeries GetSeries()
    {
        return new PhasorSeries();
    }
    ISeries IChart.GetSeries()
    {
        return GetSeries();
    }
}
公共接口IChart
{
ISeries GetSeries();
}
公共区域分类图:IChart
{
公共虚拟ISeries GetSeries()
{
抛出新的NotImplementedException();
}
}
公共类类比图表:图表,IChart
{
公共新ITimeries GetSeries()
{
返回新系列();
}
ISeries IChart.GetSeries()
{
返回GetSeries();
}
}
公共类PhasorChart:图表,IChart
{
公开新IPhasorSeries GetSeries()
{
返回新的相序列();
}
ISeries IChart.GetSeries()
{
返回GetSeries();
}
}
如果您有图表或IChart变量,则可以获取ISeries,但如果您有更具体的类型,则可以检索更具体的接口。不幸的是,看起来我无法在创建新的抽象时重写它,所以我在抛出的抽象类中使用了虚拟方法

我想使用相同的方法名,尽管我也可以创建“GetPhasorSeries”、“GetTimeSeries”方法,但是我真的想深入研究并实现这个特定的结果


我试图以一种非设计的方式弯曲泛型虽然我仍然不知道为什么你会创建一个抽象或虚拟的泛型方法。我仍然欢迎任何关于什么模式使用这个构造的想法(考虑到这个问题的所有上下文)。

@juharr:这不起作用。约束是从基本方法继承的。啊,我想我明白你的意思了。我希望子类实际上不能指定类型(这当然与获取具体类型相矛盾)。我想要的是:analogChart.GetSeries()=>返回ISeries和phasorChart。GetSeries()=>返回ISeries中的IPhasorSeries,但因为没有
public interface IChart
{
    ISeries GetSeries();
}
public abtract class Chart : IChart
{
    public virtual ISeries GetSeries()
    {
        throw new NotImplementedException();
    }
}

public class AnalogChart : Chart, IChart
{
    public new ITimeSeries<float> GetSeries()
    {
        return new Series<float>();
    }

    ISeries IChart.GetSeries()
    {
        return GetSeries();
    }
}

public class PhasorChart : Chart, IChart
{
    public new IPhasorSeries GetSeries()
    {
        return new PhasorSeries();
    }
    ISeries IChart.GetSeries()
    {
        return GetSeries();
    }
}