Reputation: 19574
I am working on a C# project to parse files of different kinds. In order to do this, I have created the following kind of class structure:
interface FileType {}
class FileType1 : FileType {}
class FileType2 : FileType {}
abstract class FileProcessor {}
class Processor_FileType1 : FileProcessor {} // Will use FileType1 - type of storage class
class Processor_FileType2 : FileProcessor {} // Will use FileType2 - type of storage class
So, since each FileProcessor
uses a different kind of FileType
, I was hoping to write some kind of method in my Base FileProcessor
class to be able to get the values from the file looking something along the lines of:
abstract class FileProcessor
{
protected List<T> getValuesFromFile<T>() where T:FileType
{
try
{
otherClass.doProcess<T>();
}
catch (Exception ex)
{
throw new Exception("Unable to retrieve the data from the file.", ex);
}
}
}
And, in another library I've been using (related to parsing Excel files), which I cannot change, I have the following kind of method:
public List<T> doProcess<T>() where T : class, new()
{
// the actual work
}
But I am getting an error in my getValuesFromFile
method stating that The type 'T' must be a reference Type
to be able to return a List in my method.
I am trying to figure out how to do this to minimize having to write the code for pulling the data from the file into each of the separate derived processor classes.
Is there any way to do this or is this just bad programming for Generics?
Upvotes: 0
Views: 58
Reputation: 43906
Your otherClass.doProcess()
method is declared like
public List<T> doProcess<T>() where T : class, new()
So this requires T
to be a reference type and to have a default parameterless constructor.
In the calling method you have only restricted T
to implement the FileType
interface:
List<T> getValuesFromFile<T>() where T:FileType
This isn't enough. An interface could also be implemented by a value type and it doesn't say anything about constructors. So you'd have to change the constraints to:
List<T> getValuesFromFile<T>() where T: class, FileType, new()
(Note that the class
constraint has to be the first in a constraint declaration).
Upvotes: 5
Reputation: 914
You can ensure that T is a reference type by constraining as:
where T : class, FileType
It’s hard for me to understand exactly what you’re trying to do, so I can’t provide guidance on your use of generics more generally.
Upvotes: 4