2009-02-04 2 views
2

переменного типа Int32 не будет threated, как Int32, если мы бросим его в «объект», прежде чем перейти к перегруженным методам ниже:методы Перенаселенности в C# .NET

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
public static void MethodName(object a) 
{ 
     if(a is int) 
     { 
       Console.WriteLine("int"); 
     } 
     else 
     { 
       Console.WriteLine("object"); 
     } 
} 
1

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

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

спасибо! но это не мое дело. –

3

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

+0

Если вы не используете виртуальные функции. – GWLlosa

+0

Хорошая точка, но виртуальные функции - это нечто иное, чем перегрузки методов. Вопрос был конкретно о перегрузках методов. –

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

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

+0

Из-за вашего ответа я переписал функции, чтобы уточнить, что писать имя типа не было целью, но оно должно было иметь разные типы поведения, основанные на типе. –

+0

Я увидел это: точка смятения была на самом деле опечаткой в ​​первом предложении вашего вопроса, который я теперь исправил. –

+0

Я собирался обновить мой, но вместо этого просто посмотрю ответ Грега ниже: он уже выражает это так, как я мог. –

3

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

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

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

не совсем то, что я хотел. Я переписал функции, чтобы уточнить, что писать имя типа не было целью, но это должно было иметь разные типы поведения, основанные на типе. –

+0

Не сложно, с ограничением, что вы должны быть в состоянии как-то определить, что тип во время компиляции. –

+0

Возможно, перегрузка - это неправильный метод, так как в этом случае, когда «объект» является одним из типов, он приводит к элементу неопределенности. Поэтому был бы более целесообразным включить аргумент .GetType()? –

10

разрешение перегрузки выполнения не будет доступен до 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 перегрузки на основе типа времени выполнения.

0

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

object a = 5; 

OverloadResolver.Invoke(MethodName, a); 

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

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

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

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); 
     } 
Смежные вопросы