在C#.NET中重载方法

时间:2009-02-04 19:46:55

标签: c# .net generics reflection overloading

如果我们在传递给下面的重载方法之前将它转换为“Object”,则Int32类型的变量将不会作为Int32进行线程化:

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

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

要将它作为Int32处理,即使它被强制转换为“Object”也可以通过反射来实现:

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

还有其他办法吗?也许使用Generics?

8 个答案:

答案 0 :(得分:10)

运行时重载决策在具有dynamic

的C#4.0之后才可用
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);

this转换为dynamic可启用动态重载支持,因此DynamicFoo包装器方法可以根据运行时类型调用最佳拟合Foo重载参数。

答案 1 :(得分:8)

public static void MethodName(object a)
{
        if(a is int)
        {
                Console.WriteLine("int");
        }
        else
        {
                Console.WriteLine("object");
        }
}

答案 2 :(得分:3)

不,调用方法的特定重载是在编译时确定的,而不是在运行时确定的,除非您使用反射,因此如果您将int转换为对象,则会调用对象重载。我不相信有任何其他方法可以做到这一点,并且泛型也不会为你做这件事。

答案 3 :(得分:3)

这不起作用吗?

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

MethodName<object>(1);
MethodName<Int32>(1);

答案 4 :(得分:2)

也许:

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

然后叫它:

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

或者:

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

最后:

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

更新:
它归结为语言必须以某种方式能够确定您将在编译时处理的类型

答案 5 :(得分:1)

如果你想要打开类型,你几乎坚持使用if / else构造。由于多态性,switch语句本身不起作用。如果您使用的是非原始对象,那么通常可以使用多态或接口来实现此类行为,例如:

public static void MethodName(MyBaseObject obj)
{
     Console.WriteLine(obj.MyVirtualFunctionCall());
}

答案 6 :(得分:1)

动态重载是一个问题,直到.NET 3.5,但使用.NET 4,它很可行,几行代码。

   public void publish(dynamic queue)
     {
         publish(queue);
         Console.WriteLine("dynamic queue publishing");
     }

     public void publish(ValidationQueue queue)
     {
         Console.WriteLine("Validation queue publishing");
     }

如何致电

     foreach (var queue in  _vodaQueueDAO.FetchAllReadyQueuesWithHighestPriority())
        {
            PublishingService.publish(queue);
        }

答案 7 :(得分:0)

我为.NET 3.5编写了一个实现,例如可以做类似的事情:

object a = 5;

OverloadResolver.Invoke(MethodName, a);

它将使用int overload。

使用已编译和缓存的Lambda表达式,因此性能应该没问题。

如果有人需要,请发邮件给我,herzmeisterderwelten,居住在gmail.com