如何将两种方法与不同的对象结合起来(两种方法中的代码相同)

how to combine 2 methods with different objects (same code in both methods)

这里是新海报,但已经使用 SO 很长时间了。

我对 C# 编码有点生疏,我想在我的代码中优化一些东西。我有 2 个方法,它们具有完全相同的代码,但具有不同的对象(对象具有一些不同的属性,但两种方法中使用的属性相同)。在调用方法之前,查询的构建方式有所不同。有没有一种方法可以轻松地组合这些方法,以便我仍然可以将它与一个或另一个对象一起使用?

private static void SetQueryMainFilters(DocumentQueryObject documentQuery, DocumentQuery repeaterQuery, out DocumentQuery outRepeaterQuery)
{
    if (documentQuery.NodeID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.NODE_ID, documentQuery.NodeID);
    }

    if (documentQuery.DocumentID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.DOCUMENT_ID, documentQuery.DocumentID);
    }

    outRepeaterQuery = repeaterQuery;
}

private static void SetQueryMainFilters(DocumentQueryObject documentQuery, MultiDocumentQuery repeaterQuery, out MultiDocumentQuery outRepeaterQuery)
{
    if (documentQuery.NodeID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.NODE_ID, documentQuery.NodeID);
    }

    if (documentQuery.DocumentID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.DOCUMENT_ID, documentQuery.DocumentID);
    }

    outRepeaterQuery = repeaterQuery;
}

调用重复方法的方法之一

public static MultiDocumentQuery RepeaterMultiDocumentQuery(DocumentQueryObject documentQuery)
{
    MultiDocumentQuery repeaterQuery = new MultiDocumentQuery();
    [...]
    SetQueryMainFilters(documentQuery, repeaterQuery, out repeaterQuery);

    return repeaterQuery;
}

目前,我有一个 MultiDocumentQuery 对象和一个 DocumentQueryObject。两种方法的代码相同,但对象不同

是否有正确的方法来避免代码重复?如果您有更好的解决方案可以提供给我,我会倾听建议。我需要能够调用多查询构建器或常规查询构建器,它们具有几乎相同的属性但行为不同。它使用 Kentico 的 DocumentQuery 和 MultiDocumentQuery。

谢谢!

您可以声明一个基 class,DocumentQueryMultiDocumentQuery 将从中继承,并且所述基 class 应该包含 WhereEquals() 方法。

public class DocumentBase
{
    public void WhereEquals() { }
}

public class DocumentQuery : DocumentBase
{
    // Other stuff
}

public class MultiDocumentQuery : DocumentBase
{
    // Other stuff
}

public class DocumentQueryObject
{
    public int NodeID { get; set; }
    public int DocumentID { get; set; }
}

然后,你可以像这样统一两种方法:

private static void SetQueryMainFilters(
    DocumentQueryObject documentQuery, 
    DocumentBase repeaterQuery, 
    out DocumentBase outRepeaterQuery)
{
    if (documentQuery.NodeID > 0)
    {
        repeaterQuery.WhereEquals();
    }

    if (documentQuery.DocumentID > 0)
    {
        repeaterQuery.WhereEquals();
    }

    outRepeaterQuery = repeaterQuery;
}

这意味着,在调用它时,您必须创建基 class 的对象,但 new 使用的是适当的类型。

DocumentBase single = new DocumentQuery();
SetQueryMainFilters(documentQuery, single, out single);
DocumentBase multi = new MultiDocumentQuery();
SetQueryMainFilters(documentQuery, multi, out multi);
private static void SetQueryMainFilters<TQuery>(DocumentQueryObject documentQuery, TQuery repeaterQuery, out TQuery outRepeaterQuery) where TQuery : DataQueryBase<TQuery>, new()
{ 
    if (documentQuery.NodeID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.NODE_ID, documentQuery.NodeID);
    }

    if (documentQuery.DocumentID > 0)
    {
        repeaterQuery.WhereEquals(KenticoConstants.DOCUMENT_ID, documentQuery.DocumentID);
    }

    outRepeaterQuery = repeaterQuery;
}