【问题标题】:c# How to return a class that specify a generic class in factory methodc#如何在工厂方法中返回一个指定泛型类的类
【发布时间】:2020-01-29 02:15:08
【问题描述】:

我想知道是否有可能做一个像这样的方法而不会在返回时出现丑陋的演员表?

    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;
        }
    }

为了简单起见,这是我的架构:

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

我的第一个想法是做一个这样的方法:

    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;
        }
    }

但似乎我的编译器不接受它。有没有办法做到这一点? 谢谢

【问题讨论】:

  • GetTextFileReaderGetBytesFileReader 的代码是什么?
  • 您可以(并且应该)对这些条件使用模式匹配而不是 if-else。

标签: c# unity3d generics factory abstract


【解决方案1】:

泛型在这里对你没有任何好处。

您目前使用T 只是指定参数之一的类型(除了查询其类型外,您甚至不使用它)。您可以像 AbstractFileReader GetReader(string filename, Object data) 一样轻松地编写它。

泛型的全部意义在于不关心类型是什么(尽管您可以对其进行限制)并且泛型类公开的所有方法都以相同的方式运行,而不管是什么类型@ 987654323@ 是(例如,Lists)。

这里不是这样。

因此,您根本不应该在这里使用泛型。只需在某处使用 GetReaderForStringGetReaderForBytes 方法,并在适当的时候返回 StandaloneTextFileReaderStandaloneBytesFileReader(或完全放弃这些方法,只使用适当的类 new)。

【讨论】:

  • 感谢您的回复。这是我的第一个实现,但我正在做一个工具箱来加速游戏的开发,我希望有一种系统可以简单地获取需要保存的数据,并实例化适当的编写器来保存该数据。但我想我会重新考虑我的架构,让工具箱的用户在保存方法中指定他的作者。谢谢
  • @LenweSeregon 真的没有必要重新实现ISerializable 或 JSON .NET,它们都已经存在并且已经提供了必要的工具。
猜你喜欢
  • 2021-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多