【问题标题】:Duplicate code from identical objects in separate namespaces来自不同命名空间中相同对象的重复代码
【发布时间】:2018-06-12 14:31:50
【问题描述】:

我正在编写一个控制台应用程序,以便使用 ReportExecution2005ReportService2010 库更轻松地管理本地 SSRS 实例,每个库都提供不同的功能。要处理现有报告,我必须从包含报告参数的 ReportServer 数据库中读取 XML 字符串,解析它们,并使用此信息来构建与服务器通信时使用的对象。为此,我编写了一个如下所示的简单函数

public static ParameterValue[] RebuildParameters(string parameters) {

        //setup xml
        XDocument main = XDocument.Parse(parameters);
        List<XElement> pElements = main.Descendants("ParameterValue").ToList();

        //rebuild param list
        ParameterValue[] newParams = new ParameterValue[pElements.Count];
        int i = 0;
        foreach (XElement param in pElements) {
            newParams[i] = new ParameterValue();
            newParams[i].Name = param.Element("Name").Value.ToString();
            newParams[i].Value = param.Element("Value").Value.ToString();
            i++;
        }

        return newParams;
}

在我需要为两个独立的命名空间使用这个辅助函数之前,一切都很好。 ParameterValue 类存在于两个命名空间(HereHere)中,但我无法在它们之间显式转换。我也尝试过设置一个通用函数,但由于类型未知,我无法分配名称或值。

public static T[] RebuildParameters<T>(string parameters) where T : new() {
        //setup xml
        XDocument main = XDocument.Parse(parameters);
        List<XElement> pElements = main.Descendants("ParameterValue").ToList();

        //rebuild param list
        T[] newParams = new T[pElements.Count];
        foreach (XElement param in pElements) {
            newParams[i] = new T();
            //not allowed
            newParams[i].Name = param.Element("Name").Value.ToString();
            newParams[i].Value = param.Element("Value").Value.ToString();
        }
        return newParams;
    }

在知道代码相同的情况下,编写一个可供来自不同命名空间的两个类使用的单一辅助方法的最佳方法是什么?

【问题讨论】:

    标签: c# sql-server reporting-services


    【解决方案1】:

    你说得对,这些类型不能转换,因为它们代表完全不同的类型。但是,在查看它们之后,它们看起来像是非常简单的对象,您可以选择映射它们。假设您可以使用链接文档表明您应该能够执行此操作的相同形式:

    public ReportService2010.ParameterValue Map(ReportExecution2005.ParameterValue data)
    {
        return new ReportService2010.ParameterValue()
        {
            Label = data.Label,
            Name = data.Name,
            Value = data.Value
        };
    }
    
    public ReportService2005.ParameterValue Map(ReportExecution2010.ParameterValue data)
    {
        return new ReportService2005.ParameterValue()
        {
            Label = data.Label,
            Name = data.Name,
            Value = data.Value
        };
    }
    

    【讨论】:

    • 谢谢!虽然这可行,但一旦我在一个命名空间中拥有参数值数组,我现在就有了一个函数,它将循环遍历它们并重新映射到另一个命名空间......这本质上是原始函数的重复。有没有办法创建一个函数来满足我的需要......泛型、应用于这些类的接口或其他任何东西?如果这是我能接受的最好方法,我只是希望有一些更清洁的东西。
    • @KorbenDallas 我不认为我在关注你。当您说基本上是原始功能的重复时,您指的是什么原始功能?您能否详细说明您希望从单个函数中获得什么行为?
    • 我的原始函数(第一个代码块),解析 xml 字符串,然后循环遍历结果以创建一个 ParameterValues 数组。根据您的建议,我可以为 ReportService2005 执行此操作,但如果需要 ReportService2010 数组,我会再次循环遍历它以将值映射到正确的命名空间/类。单个函数只需要一个循环。解析 XML -> 循环并创建所需的 ParameterValue 对象 -> 返回正确的命名空间数组。没有映射或转换,这就是我追求通用函数的原因。同样,我不确定这是否可能。
    • 好吧,我不认为直接的通用函数会让你到达那里,因为任何约束都是and。但是,另一种可能性是使用AutoMapper,它应该能够在没有配置的情况下映射您的类,因为属性名称是匹配的。
    • 另一个想法:如果您将这两种类型都表示为基本 xml,您应该能够将该 xml 表单反序列化为任何一种类型。这比解析 xml 更容易,你会得到这两种类型。
    猜你喜欢
    • 2017-08-31
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 2015-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多