I know how to accomplish my goal when using a generic class. But to understand why the syntax of generic methods is allowed (to be declared virtual or abstract) in a non-generic class I can't seem to determine.
The first chunk of code shows a simple example using a generic class to create an abstract method that returns more specific interface than the one constrained in the base class.
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();
}
}
Now, if remove the generic type from the Chart class but keep the generic method with the ISeries constraint I get errors on the following.
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();
}
}
It appears I don't fully understand what is going on when implementing a generic method in a non-generic class. When a generic class is used--there exist multiple class definitions. What does it mean when you only have a generic method? Are there actually multiple methods? or does it somehow just call the same method?
If this is essentially not supported with abstract and virtual keywords, I would have expected to get an error when creating an abstract generic method. How would one properly use an abstract generic method if you cannot use the syntax here to avoid casting in other code. (I can't even cast the T to an ISeries-- it appears the constraint is lost in the subclass as if it doesn't know T must be an ISeries)
Note the purpose of the question here is to understand what is going on not to work around this problem or have different 'solutions' proposed.