Перегрузка методов в C # .NET - PullRequest
2 голосов
/ 04 февраля 2009

Переменная типа Int32 не будет считаться Int32, если мы приведем ее к «Object» перед передачей перегруженным методам ниже:

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

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

Чтобы обработать его как Int32, даже если он приведен к «Объекту», можно добиться с помощью отражения:

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

Есть ли другой способ сделать это? Может быть, с использованием Generics?

Ответы [ 8 ]

10 голосов
/ 04 февраля 2009

Разрешение перегрузки во время выполнения не будет доступно до C # 4.0, который имеет 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);

Приведение this к dynamic включает поддержку динамической перегрузки, поэтому метод-обертка DynamicFoo может вызвать перегрузку Foo с наилучшим соответствием в зависимости от типа аргумента времени выполнения.

8 голосов
/ 04 февраля 2009
public static void MethodName(object a)
{
        if(a is int)
        {
                Console.WriteLine("int");
        }
        else
        {
                Console.WriteLine("object");
        }
}
3 голосов
/ 04 февраля 2009

это не сработает?

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

MethodName<object>(1);
MethodName<Int32>(1);
3 голосов
/ 04 февраля 2009

Нет, конкретная перегрузка вызываемого метода определяется во время компиляции, а не во время выполнения, если вы не используете отражение, поэтому, если вы приведете свой int к объекту, будет вызвана перегрузка объекта , Я не верю, что есть какой-то другой способ сделать это, и дженерики не сделают это и для вас.

2 голосов
/ 04 февраля 2009

Возможно:

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);
}

Обновление:
Это сводится к тому, что язык должен каким-то образом определять, с каким типом вы будете иметь дело во время компиляции .

1 голос
/ 11 ноября 2011

динамическая перегрузка была проблемой до .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);
        }
1 голос
/ 04 февраля 2009

Вы в значительной степени застряли с конструкциями if / else, если хотите включить типы. Сам оператор switch не будет работать из-за полиморфизма. Если вы используете не примитивные объекты, то обычно вы можете выполнить такое поведение с помощью полиморфизма или интерфейсов, например:

public static void MethodName(MyBaseObject obj)
{
     Console.WriteLine(obj.MyVirtualFunctionCall());
}
0 голосов
/ 14 апреля 2009

Я написал реализацию для .NET 3.5, где вы, например, может сделать что-то вроде:

object a = 5;

OverloadResolver.Invoke(MethodName, a);

и будет использоваться перегрузка int.

Работает с скомпилированными и кэшированными лямбда-выражениями, поэтому производительность должна быть в порядке.

Если кому-то это нужно, напишите мне, herzmeisterderwelten, который проживает на gmail.com

...