Reputation: 957
I am having problem with my design:
I have some base class
public class ReportConfig<T> where T: class
{
public string ReportSavePath { get; set; }
public string ReportTitle { get; set; }
public T ReportData { get; set; }
}
and this class can be extended into (one of possible subclass presented):
public class CsvReportConfig<T> : ReportConfig<T> where T : class
{
// some extra class specific props
}
Then, I have a ReportGenerator abstract class
public abstract class ReportGenerator<T> where T : ReportConfig<T>
{
public ReportGenerator(ReportConfig<T> config)
{
Config = config;
}
public ReportConfig<T> Config { get; set; }
public abstract ReportGenerationResult GenerateReport();
}
and then, I would like to extend the ReportGenerator
class into:
public class Csv1ReportGenerator : ReportGenerator<CsvReportConfig<DataObj>>
{
public Csv1ReportGenerator (CsvReportConfig<DataObj> config) : base(config)
{
}
public override ReportGenerationResult GenerateReport()
{
throw new NotImplementedException();
}
}
And here, I am receiving an error that
CsvReportConfig<DataObj>
cannot be used as type parameter 'T' in generic type or methodReportGenerator<T>
.
What am I doing wrong and how to correct this?
Upvotes: 2
Views: 82
Reputation: 62213
I believe this is what you are trying to do
public class ReportGenerationResult { }
public class DataObj { }
public class ReportConfig<T> where T : class
{
public string ReportSavePath { get; set; }
public string ReportTitle { get; set; }
public T ReportData { get; set; }
}
public class CsvReportConfig<T> : ReportConfig<T> where T : class
{}
public abstract class ReportGenerator<T,U> where T : ReportConfig<U> where U : class
{
protected ReportGenerator(T config)
{
Config = config;
}
public T Config { get; set; }
public abstract ReportGenerationResult GenerateReport();
}
public class Csv1ReportGenerator : ReportGenerator<CsvReportConfig<DataObj>, DataObj>
{
public Csv1ReportGenerator(CsvReportConfig<DataObj> config) : base(config)
{
}
public override ReportGenerationResult GenerateReport()
{
throw new NotImplementedException();
}
}
These are the main changes that were made.
ReportGenerator
- This was the main change. It looks like you want to specify a generic type parameter for the property Config
(constrained to types that are or extend ReportConfig<T>
) in any implementations. To do this and to keep the ReportConfig.ReportData
generic you have to use 2 generic type parameters where the second type parameter is reused to constrain ReportConfig<T>
.Csv1ReportGenerator
- now when this inherits ReportGenerator<CsvReportConfig<DataObj>, DataObj>
instead of ReportGenerator<CsvReportConfig<DataObj>>
which now enables this type to have property Config
which would be constrained to type CsvReportConfig<DataObj>
which is what you were trying to do.Upvotes: 4