2011-02-05 2 views
1

Использование C# 4.0, есть ли способ разрешить метод (без создания перегрузки) принять строку или int, а затем разрешить мне определить, какой тип был передан?Как разрешить метод принимать строку или int?

+4

Это именно то, для чего предназначены перегруженные методы. Почему вы против их использования? –

+0

Согласен с Коди. Это можно сделать, но это не может быть сделано очень красиво. И у меня, и у Коди есть два предложения ниже, но это не очень хороший способ сделать это, действительно. – Bebben

+0

Спасибо Коди. Я не против, я просто хотел убедиться, что я не пропустил простую, новую функцию в 4.0, которая позволила бы это сделать. Поскольку теперь возможно делать необязательные и названные типы, я подумал, что, возможно, появился новый чистый способ сделать это. Благодаря! – user390480

ответ

15

Поскольку вы используете C# 4.0, вы можете написать generic method. Например:

void MyMethod<T>(T param) 
{ 
    if (typeof(T) == typeof(int)) 
    { 
     // the object is an int 
    } 
    else if (typeof(T) == typeof(string)) 
    { 
     // the object is a string 
    } 
} 

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

+1

+1 для объяснения лучшей практики –

+0

+1 Я согласен с Коди. Пожалуйста, используйте перегрузки, если это возможно! – Bebben

+3

Согласитесь с запахом вокруг примера; здесь есть две перегрузки. –

4

Уверен, что вы можете! Примером этого является

public void MyMethod(object o) 
    { 
     if (o.GetType() == typeof(string)) 
     { 
      //Do something if string 
     } 
     else if (o.GetType() == typeof(int)) 
     { 
      // Do something else 
     } 
    } 
+0

Вы можете сделать это так, но это накладывает штраф за производительность, потому что 'int' помещается в« объект ». Поскольку вопросник использует C# 4.0, дженерики - намного лучший вариант. –

1

Вы можете обернуть строку и Int в некоторой обертке с маркером интерфейсом и передать их методу.

Что-то вроде этого

interface IMyWrapper<T> { T Value {get; }} 
public class StringWrapper: IMyMarker<string> { ... } 
public class IntWrapper: IMyMarker<int> { ... } 

void MyMethod<T>(IMyWrapper<T> wrapper) 
{ 
} 
+0

Почему в мире вы бы это сделали, вместо того, чтобы писать общий метод? –

+1

Код Серый, если вы можете показать мне хороший пример, как я могу ограничить общий метод * int * и * double * только без исключения исключения во время выполнения, тогда я бы этого не сделал. –

+0

Я не уверен, почему исключение во время выполнения будет проблемой. Если вы * пропустили * запрещенный тип к рассматриваемому методу, вы бы * хотели бы * поймать это во время отладки, поэтому исключение во время выполнения кажется идеальным. Этот случай будет проблемой в вашем коде. * Исключительно * редко, что конечный пользователь динамически вызывает ваш метод и задает произвольный тип данных. И даже если это так, что происходит в вашем сценарии? Они по-прежнему получают ошибку во время выполнения: подпись метода не совместима с указанными аргументами. –

1

Я думаю, что перегрузка метод был бы простым решением, если вы хотите, чтобы держаться подальше от вещей, как отражение или проверки типов.

public void MethodName(string foo) 
{ 
    int bar = 0; 
    if(int.tryparse(foo)) 
     return MethodName(bar);//calls int overload 
} 
Смежные вопросы