0

I'm adding a new generic Serialize method for my Serializer class. And old one must be obsolete.

[XmlRoot("a")]
public class A
{
    [XmlElement("field")]
    public string Field;
}

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        a.Field = "filed value";

        Console.WriteLine(Serialize(a));//this calls generic version !?
        Console.WriteLine();
        Console.WriteLine(Serialize(null));//ok
        Console.WriteLine();
        Console.WriteLine(Serialize<A>(a));//ok, we explicitly called generic version
    }

    [Obsolete("Use Serialize<T> instead")]
    public static string Serialize(Object pObject)
    {
        return "You have called old Serialize method";
    }

    public static string Serialize<T>(T value)
    {
        return "You have called new Serialize<T> method";
    }
}

Expected result should be:

You have called old Serialize method

You have called old Serialize method

You have called new Serialize<T> method

But the result is:

You have called new Serialize<T> method

You have called old Serialize method

You have called new Serialize<T> method

So why Serialize(a) calls the generic version? Is there a bug for generic obsoleted methods?

  • The types are [inferred at compile time](http://stackoverflow.com/a/4976972/11683). – GSerg Jan 26 '14 at 17:22
  • Overload resolution rules can be a bit opaque. But this is a clear one, it really does favor an *exact* match with the argument type over a conversion to Object. – Hans Passant Jan 26 '14 at 18:13
  • :/ It seems we have to change the method name.. Or move it to another namespace.. – burc akbas Jan 26 '14 at 21:27

1 Answers1

1

If you cast a to object you will get the expected result

Console.WriteLine(Serialize((object)a))
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • well, ok but we don't want to change the code. there are thousands of code block using the old code. – burc akbas Jan 26 '14 at 17:18
  • @burcakbas But you want that old code to call the new version, don't you? Your message in the attribute suggests that simply calling the generic version is correct. In that case, you don't need to change the old code, you just need to recompile it. –  Jan 26 '14 at 17:21
  • @hvd No, i don't want that. Because there is a few new things in the new one and that cause side effects for our business logic. I just want to warn the developer like "ok, you can use the old code but this is obsolete. Change to the new one if you can." – burc akbas Jan 26 '14 at 17:27
  • 1
    @burcakbas You can't. Because of the type inference the generic version will always be called, unless the parameter perfectly matches the non-generic signature (i.e., is `object`). This is a very core feature of C#, and if you don't like it, you probably better give the generic method a different name. – GSerg Jan 26 '14 at 17:34