views:

1257

answers:

7

A variable of the type Int32 won't be threated as Int32 if we cast it to "Object" before passing to the overloaded methods below:

public static void MethodName(int a)
{
 Console.WriteLine("int");
}

public static void MethodName(object a)
{
 Console.ReadLine();
}

To handle it as an Int32 even if it is cast to "Object" can be achieved through reflection:

public static void MethodName(object a)
{
 if(a.GetType() == typeof(int))
 {
  Console.WriteLine("int");
 }
 else
 {
  Console.ReadLine();
 }
}

Is there another way to do that? Maybe using Generics?

+7  A: 
public static void MethodName(object a)
{
        if(a is int)
        {
                Console.WriteLine("int");
        }
        else
        {
                Console.WriteLine("object");
        }
}
CodeMonkey1
+1  A: 

You're pretty much stuck with if/else constructs if you're looking to switch on types. The switch statement itself won't work due to polymorphism. If you're using non-primitive objects, than you can usually accomplish this sort of behavior either with polymorphism or interfaces, such that:

public static void MethodName(MyBaseObject obj)
{
     Console.WriteLine(obj.MyVirtualFunctionCall());
}
GWLlosa
thanks! but it is not my case.
Jader Dias
+3  A: 

No, the specific overload of a method that is called is determined at compile-time, not at runtime, unless you're using reflection, thus if you've cast your int to an object, the object overload will be called. I don't believe there's any other way to do this, and generics won't do it for you either.

David Morton
Unless you're using virtual functions.
GWLlosa
Good point, but virtual functions are a different thing than method overloads. The question was specifically about method overloads.
David Morton
+2  A: 

Perhaps:

public static void MethodName(Type t)
{
     Console.WriteLine(t.Name);
}

Then call it:

int a = 0;
string b = "";
object c = new object();
MethodName(a.GetType());
MethodName(b.GetType());
MethodName(c.GetType());

Or:

public static void MethodName<T>(T a)
{
    Console.WriteLine(a.GetType().Name);
}

And finally:

public static void MethodName<T>()
{
    Console.WriteLine(typeof(T).Name);
}


Update:
It comes down to the fact that the language must somehow be able to determine what type you will be dealing at compile time.

Joel Coehoorn
Because of your answer I have rewritten the functions to clarify that writing the type's name was not the goal, but it was to have different behaviors based on the type.
Jader Dias
I saw that: the confusion point was actually a typo in the first sentence of your question, which I have now fixed.
Joel Coehoorn
I was going to update mine, but instead just see Greg's answer below: he already expresses it as well as I could.
Joel Coehoorn
okay - copy that
Jader Dias
+3  A: 

would this not work?

void MethodName<T>(object a){
    T item = a as T;
    // treat in the manner you require
}

MethodName<object>(1);
MethodName<Int32>(1);
Greg B
not exactly what I wanted. I have rewritten the functions to clarify that writing the type's name was not the goal, but it was to have different behaviors based on the type.
Jader Dias
Not hard, with the constraint that you have to be able to somehow determine what the type is at compile time.
Joel Coehoorn
maybe overloading is the wrong method then, as in this case, with "object" being one of the types, it leads to an element of ambiguity. Therefore would a switch on the argument.GetType() be more appropriate?
Greg B
+4  A: 

Runtime overload resolution will not be available until C# 4.0, which has dynamic:

public class Bar
{
    public void Foo(int x)
    {
        Console.WriteLine("int");
    }

    public void Foo(string x)
    {
        Console.WriteLine("string");
    }

    public void Foo(object x)
    {
        Console.WriteLine("dunno");
    }

    public void DynamicFoo(object x)
    {
        ((dynamic)this).Foo(x);
    }
}

object a = 5;
object b = "hi";
object c = 2.1;

Bar bar = new Bar();
bar.DynamicFoo(a);
bar.DynamicFoo(b);
bar.DynamicFoo(c);

Casting this to dynamic enables the dynamic overloading support, so the DynamicFoo wrapper method is able to call the best fitting Foo overload based on the runtime type of the argument.

Daniel Earwicker
A: 

I wrote an implementation for .NET 3.5 where you e.g. can do something like:

object a = 5;

OverloadResolver.Invoke(MethodName, a);

and it would use the int overload.

Works with compiled and cached Lambda expressions so the performance should be ok.

If anybody needs it, mail me, herzmeisterderwelten, who resides at gmail.com

herzmeister der welten