【问题标题】:Overloading a Method based upon return types根据返回类型重载方法
【发布时间】:2012-06-26 21:36:57
【问题描述】:

全部—— 我的一个类中有这两种方法:

public static void DeSerializeFromXml(out cDBData db, string pathToXML)
{
    using (XmlTextReader reader = new XmlTextReader(pathToXML))
    {
        XmlSerializer ser = new XmlSerializer(typeof(cDBData));
        db = (cDBData)ser.Deserialize(reader);
    }
}

public static void DeSerializeFromXml(out cDatabases db, string pathToXML)
{
    using (XmlTextReader reader = new XmlTextReader(pathToXML))
    {
        XmlSerializer ser = new XmlSerializer(typeof(cDatabases));
        db = (cDatabases)ser.Deserialize(reader);
    }
}

它们工作正常,但我想知道为什么我不能根据方法的返回类型创建方法重载。我以为我读到这在某处是可能的,但我显然错了,因为它不起作用:

public static cDBData DeSerializeFromXml(string pathToXML)
{
    cDBData db;

    using (XmlTextReader reader = new XmlTextReader(pathToXML))
    {
        XmlSerializer ser = new XmlSerializer(typeof(cDBData));
        db = (cDBData)ser.Deserialize(reader);
    }
    return db;
}

public static cDatabases DeSerializeFromXml(string pathToXML)
{
    cDatabases db;

    using (XmlTextReader reader = new XmlTextReader(pathToXML))
    {
        XmlSerializer ser = new XmlSerializer(typeof(cDatabases));
        db = (cDatabases)ser.Deserialize(reader);
    }
    return db;
}

感谢您的周到回复

感谢 dlev,这是最终的解决方案

    public static T DeSerializeFromXml<T>(string pathToXML)
    {
        T db;

        using (XmlTextReader reader = new XmlTextReader(pathToXML))
        {
            XmlSerializer ser = new XmlSerializer(typeof(T));
            db = (T)ser.Deserialize(reader);
        }
        return db;
    }

    public static void SerializeToXml<T>(T db, string pathToXML)
    {
        using (var fileStream = new FileStream(pathToXML, FileMode.Create))
        {
            var ser = new XmlSerializer(typeof(T));
            ser.Serialize(fileStream, db);
        }
    }

我想在搜查警察关闭这个问题之前发布这些内容。

【问题讨论】:

标签: c# return-value overloading


【解决方案1】:

您不能这样做,因为 C# 根本不支持这种重载。您可以通过使方法泛型并返回泛型参数类型来实现类似的效果:

public static T DeSerializeFromXml<T>(string pathToXML)
{
    T db;

    using (XmlTextReader reader = new XmlTextReader(pathToXML))
    {
        XmlSerializer ser = new XmlSerializer(typeof(T));
        db = (T)ser.Deserialize(reader);
    }
    return db;
}

然后你可以像这样调用函数:

DeSerializeFromXml<cDatabases>(pathToXml);

虽然这不是您想要的,但它确实具有只需要一个方法的好处。

【讨论】:

  • 这是实现此类功能的最佳方式 - 您还可以约束 T 并使用泛型做一些非常强大的东西,例如约束到“新”等。我使用创建了一个基本映射器类AutoMapper 库,它使用泛型为我的所有对象提供默认 DTO 映射
  • 您先生是个天才!感谢您提供简单的解决方案。
【解决方案2】:

我想知道为什么我不能根据方法的返回类型创建方法重载。

这根本不可能。在重载决议期间不考虑返回类型,并且该语言只是禁止尝试像这样重载。来自 C# 4 规范的第 3.6 节:

方法的签名由方法的名称、类型参数的数量以及每个形式参数的类型和种类(值、引用或输出)组成,按从左到右的顺序考虑。出于这些目的,出现在形式参数类型中的方法的任何类型参数都不是通过其名称来标识的,而是通过其在方法的类型参数列表中的序号位置来标识的。方法的签名具体不包括返回类型、可能为最右边的参数指定的 params 修饰符,也不包括可选的类型参数约束。

请注意,此处包含返回类型。然后我们有:

签名是类、结构和接口中成员重载的启用机制:

  • 方法重载允许类、结构或接口声明多个具有相同名称的方法,前提是它们的签名在该类、结构或接口中是唯一的。

就这样做的动机而言,如果表达式的类型取决于表达式的使用方式,那会使生活变得非常复杂。对于某些表达式(例如 null 和 lambda 表达式), 是这种情况,但对于方法调用等则不然。您最终可能会遇到一些非常奇怪的情况:

public void Foo(int x) {}
public void Foo(long y) {}

public int Bar() {}
public long Bar() {}

Foo(Bar()); // What would this call?

【讨论】:

  • 正如你所说,它是 C# 的一个属性。我记得 Don Box 关于 CLR 的书——你肯定知道,Jon :)——CLR 确实在技术上支持这种重载,但它没有以我所知道的任何语言实现。
【解决方案3】:

为什么不直接返回一个通用对象?在这种情况下,您可能不需要超载。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多