【问题标题】:Passing a new instance of a Type through a Generic Method通过通用方法传递类型的新实例
【发布时间】:2018-11-28 15:33:10
【问题描述】:

我有一系列非常相似的方法:

    private static DocumentBody GetPdfBodyObject(int sectionId)
    {
        DocumentBody db = new DocumentBody();
        // Add some stuff to Db
        return db;
    }

    private static DocumentHeader GetPdfHeaderObject(int sectionId)
    {
        DocumentHeader dh = new DocumentHeader();
        // Add some stuff to DH - similar to above
        return dh;
    }

等等……

如您所见,这两个示例之间的区别在于被实例化和返回的类型。

所以我立刻想到使用通用方法来减少代码重复......我似乎无法弄清楚哪种方法是“最佳实践”,我可以在不使用反射的情况下获得我需要的东西吗?

我根本没有使用过泛型方法,所以欢迎任何建议。

【问题讨论】:

  • 似乎您可以使用工厂,假设您的所有类型都继承自一个公共基类或实现一个公共接口。但我不确定标题和正文有什么共同点......
  • 您实际上可以尝试使方法通用并使用 Activator 类(请参阅:docs.microsoft.com/pl-pl/dotnet/api/…)来创建适当的实例。不过,工厂听起来对我来说是个更好的主意
  • 上述 cmets 暗示的部分有多相似? DocumentBodyDocumentHeader 是否共享任何公共接口/基类?
  • 他们目前没有,但他们很快就会。此代码序列严格只更新公共属性,因此将完成并测试其中的一些想法。

标签: c# generics reflection types


【解决方案1】:

这里的最佳做法是将静态方法重构为工厂方法或使用builder pattern,如果它是您正在构建的更大对象(似乎是这种情况)。泛型方法的使用在这里仅限于无参数构造函数——只要构造函数接受参数,您就需要使用 Activator,它是反射,您通常不想要这样的代码。话虽如此:您使用无参数构造函数构造对象的两种方法,因此您可以将两者都重构为:

private static TT GetPdfObjectPart<TT>(int sectionId) where TT : class, new()
{
    TT dh = new TT();
    // Add some stuff to DH - similar to above
    return dh;
}

另请注意,正如@dymanoid 指出的那样——在这种情况下,您只能使用合同的一部分(where 条款)——因此您需要实施 所有构造类型的一些“通用”接口 - 您将仅限于接口中的方法。使用构建器模式看起来真的很经典。

【讨论】:

  • "Some stuff" 在这种情况下只能是 dh.GetHashCode()dh.ToString(),因为在编译时没有信息是什么类型的对象。
  • 因此,构建器模式将是我的选择。但是感谢您指出这一点,我会修改我的答案
【解决方案2】:

对我来说,界面很好:

private interface IDocumentPart
{
}

private class DocumentHeader : IDocumentPart
{
}

private class DocumentBody : IDocumentPart
{
}

private static T GetPdfPart<T>(int sectionId) where T : IDocumentPart, new()
{
       var doc = new T();
       return doc;
}

当然,您可以在接口中为所有类定义一些通用的属性和方法。

【讨论】:

  • 完美!不久前我读到了这个方法的功能,想知道我什么时候可以把它付诸实践——它刚刚从我的雷达上消失了!非常感谢,工作愉快!
猜你喜欢
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多