简体   繁体   中英

c# How to return a class that specify a generic class in factory method

I would like to know if it's possible to do a method like this one without that ugly cast on the return?

    public static AbstractFileReader<T> GetReader<T>(string filename, T data)
    {
        if(data is string)
        {
            return GetTextFileReader(filename) as AbstractFileReader<T>;
        }
        else if(data is byte[])
        {
            return GetBytesFileReader(filename) as AbstractFileReader<T>;
        }
        else
        {
            Debug.LogError("There is no reader for that type of data : " + data.GetType().ToString());
            return null;
        }
    }

To make it simple, this is my architecture:

> AbstractFileReader<T> => The generic base class
> AbstractTextFileReader : AbstractFileReader<string> => an abstract class
> StandaloneTextFileReader : AbstractTextFileReader => the final implementation

My first thought was to do a method like this one:

    public static AbstractFileReader<T> GetReader<T>(string filename, T data)
    {
        if(data is string)
        {
            return StandaloneTextFileReader(filename);
        }
        else if(data is byte[])
        {
            return StandaloneBytesFileReader(filename);
        }
        else
        {
            Debug.LogError("There is no reader for that type of data : " + data.GetType().ToString());
            return null;
        }
    }

But it's seems like my compiler doesn't accept it. Is there any way to achieve that? Thanks

Generics aren't doing you any favors here.

All you're using T for at the moment is to specify the Type of one of the parameters (which you don't even use except to query its Type). You could just as easily write that as AbstractFileReader GetReader(string filename, Object data) .

The whole point of generics is to not care what the Type is (though you can put restrictions on it) and that all methods that the generic class exposes operates the same way regardless of what Type T is (for example, List s).

Which is not the case here.

As such, you shouldn't be using Generics here at all. Just have a GetReaderForString and GetReaderForBytes methods somewhere and return either a StandaloneTextFileReader or StandaloneBytesFileReader as appropriate (or dispense with the methods entirely and just new the appropriate class).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM