C# 混合泛型、非泛型和基类设计问题

C# 混合泛型、非泛型和基类设计问题,c#,C#,我的应用程序处理不同格式的数据。让我们为这个例子假设两个:类型A和类型B。因此,我创建了一个IFormatter接口: interface IFormatter { bool SomeOtherProp { get; } string Serialize(object o); T Deserialize<T>(string s); } 我还有第三个容器类型类。它保存内容类型和序列化/格式化数据: public Content { public string C

我的应用程序处理不同格式的数据。让我们为这个例子假设两个:类型A和类型B。因此,我创建了一个IFormatter接口:

interface IFormatter
{
   bool SomeOtherProp { get; }
   string Serialize(object o);
   T Deserialize<T>(string s);
}
我还有第三个容器类型类。它保存内容类型和序列化/格式化数据:

public Content
{
  public string ContentType { get; private set; }
  public byte[] Data { get; private set; }
}
在我的应用程序的一个区域中,我负责创建内容对象:

void SomeMethodForTypeA()
{
   _content = new Content(new TypeAFormatter(), theContent);
}

void SomeMethodForTypeB()
{
   _content = new Content(new TypeBFormatter(), theContent);
}
内容的构造函数执行以下操作:

Content(IFormatter formatter, object content)
{
  Data = formatter.Serialize(content);
}
在我的应用程序的另一个区域中,我有一个IFormatters列表:

List<IFormatter> lstFormatters;
列出格式化程序;
当数据传入时,我循环遍历列表,为传入数据的类型选择正确的格式化程序,并调用反序列化方法:

formatter.Deserialize<T>(data);
格式化程序。反序列化(数据);
这一切都很好

问题是,IFormatter接口反序列化是泛型的,这正是我所需要的,但是TypeAFormatter可以处理任何类型T,而TypeBFormatter专门用于处理字符串

所以我就这样做了:

    public override string Serialize(object obj)
    {
        if (obj.GetType() != typeof(string))
            throw new Exception("must be string");

    public override T Deserialize<T>(string obj)
    {
        if (typeof(T) != typeof(string))
            throw new Exception("must be string);
公共重写字符串序列化(对象obj)
{
if(obj.GetType()!=typeof(字符串))
抛出新异常(“必须是字符串”);
公共重写T反序列化(字符串obj)
{
if(typeof(T)!=typeof(string))
抛出新异常(“必须是字符串”);
这也“有效”。但我不喜欢手动类型检查。我最初是将IFormatter改为IFormatter,使其看起来像:

public class TypeAFormatter<T> : IFormatter<T>
public class TypeBFormatter : IFormatter<string>
公共类类型格式:IFormatter
公共类TypeBFormatter:IFormatter
这解决了创建方面的问题,但是我不能有一个iformatter的列表,在没有一堆反射的情况下调用类型化方法,然后它最终几乎被作为一个对象装箱


我可以采取的任何方法都不必进行类型检查,但仍然可以为反序列化通用地调用它们?

具有通用和非通用版本的接口,并根据您是否知道编译时类型来使用它们

interface IFormatter
{
   string Serialize(object o);
   object Deserialize(string s);
}

interface IFormatter<T> : IFormatter
{
   string Serialize(T o);
   T Deserialize<T>(string s);
}
此外,您可能希望在非泛型版本中有一个方法来检查实现是否可以处理特定类型:

CanFormat(Type type);  // in case you know the type only
CanFormat(object obj); // in case you know the value
然后您可以选择正确的格式化程序,如下所示:

var formatter = allFormatters.FirstOrDefault(f => f.CanFormat(myType));

是的,你仍然在做类型检查,这就是我现在正在做的。我试图避免。你根本无法避免。封装它。我刚刚找到了一种不用类型检查的方法。IFormatter只有t反序列化();IFormatter有字符串序列化(t)然后我有一个内容,它只保存公共属性和Content,Content接受序列化的类型化参数。因此TypeAFormatter变成了IFormatter,IFormatter和TypeBFormatter变成了IFormatter,IFormatter。序列化和反序列化被分为两个不同的接口:泛型和非泛型,内容也是如此。以此类推在创建端,我可以使用类型化/泛型方法,在读取端,我可以使用泛型方法。我不确定我是否喜欢拆分接口lol,但它看起来更干净,然后到处进行类型检查。
CanFormat(Type type);  // in case you know the type only
CanFormat(object obj); // in case you know the value
var formatter = allFormatters.FirstOrDefault(f => f.CanFormat(myType));