2012-05-22 7 views
1

Мне было интересно: вы бы использовали просто объект в качестве параметра в вашем методе? Моя причина этого - перегрузка. В настоящее время я пытаюсь создать метод, который подходит ко многим различным типам данных: string, decimal, DateTime ... этот список можно продолжить.Использование типа объекта в качестве параметра

Это становится немного грязным, поэтому я думал сделать следующий

public void GenericMethod(object val) 
{ 
    if (val is string) 
     // process as string 
    else if (val is decimal) 
     // process as decimal 
    else if (val is DateTime) 
     // do something for dt 
    else 
     // ... 
} 

Что вы думаете о таком методе? Не повлечет ли он лишние накладные расходы? (во время проверки типа) Вы реализовали его? Сообщите мне ...

EDIT: Да, и я просто знаком с перегрузкой. Но это становится немного раздражающим, когда есть больше чем 10 перегрузок ...

+1

Хотя это технически работает, это, конечно, не очень хорошая идея, если у вас нет * очень убедительной причины для этого. –

+0

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

ответ

7

Мне было интересно об этом: поддерживаете ли вы просто использование объекта в качестве параметра в своем методе?

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

Если вы можете принять любого типа, и вы будете обрабатывать не-специально поддерживаемый тип в некотором хорошо известном способе, то это нормально принять object. Это то, что LINQ to XML делает повсюду, и результат - очень чистый API. Я бы сделал это очень осторожно - это редко хорошая идея.

И да, накладные расходы. Я обычно не делал бы это основанием для решения - накладные расходы будут достаточно малы, чтобы в большинстве случаев быть незначительными. Создайте свой API так, как только сможете, а затем выясните, не вызовет ли это узкое место.

9

Да, это сработает. Однако есть лучшие способы сделать это.

Лучше всего использовать перегруженные:

public void GenericMethod(string val) 
{ 
     // process as string 
} 
public void GenericMethod(decimal val) 
{ 
    // process as decimal 
} 

т.д.

Всякий раз, когда вы используете is ключевое слово в коде, огромный намек, что вы, вероятно, забывая использовать некоторые важные o.o. принципы: перегрузки, подклассы и т. п.

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

Еще одна причина, по которой избегать техники «типа включения», - это согласованность с платформой .NET (и, следовательно, ожиданиями людей). Следуйте за Console.Write и другим широким спектром методов, которые переопределяются внутри и под определенным классом.

+0

Да, мы все прошли через «почему, черт возьми, ты сделал это так» и «где в мире эта ошибка возникает из ситуаций». Я думал, что другим людям может показаться, что эффективнее иметь только один метод работы, вместо того, чтобы прокладывать себе путь через множество перегрузок. – matt

+0

@matt ... на самом деле не правда. Я привык к тому, как .NET делает вещи: одна перегрузка для каждого типа, и если вы попытаетесь ее изменить, я бы смутился. – Crisfole

3

Да, это может привести к накладным расходам как для проверки типа, так и для бокса/отмены использования типа значения. Я бы рекомендовал перегрузки.

Другая возможность, если вы не делаете много математики с номером, должна была бы сделать ее универсальным методом. Арифметика довольно сложна с дженериками, хотя нет ограничений для типов значений, что позволяет использовать операторы.

1

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

Но это не перегрузка. Перегрузки будет определять различные подписи для того же имени метода, как это:

public void GenericMethod(string val) 
{ 
    // process as string 
} 

public void GenericMethod(decimal val) 
{ 
    // process as decimal 
} 

public void GenericMethod(DateTime val) 
{ 
    // do something for dt 
} 

// Etc. 

И в некоторых случаях такой подход имеет смысл.

+0

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

0

Реализация многих перегрузок, одна из которых принимает object, не представляет проблемы. Взгляните на Console.WriteLine перегрузки, например. http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx Однако, позаботиться о том, ИНТ, например, может вступать в противоречие с двойным:

int sum(int i, int j) 
{ 
return i + j; 
} 

double sum(double i, double j) 
{ 
return i + j; 
} 

object sum(object i, object j) 
{ 
    return i.ToString() + j.ToString(); 
} 

============================== 

static void Main() 
{ 
    sum(1, 2); // Error: ambigous call between `int` and `double` versions 
    sum(1.0, 2.0); // calls double version, although 1.0 and 2.0 are objects too 
    sum("Hello", "World"); // object 
} 
3

Нет необходимости тех!

Просто объявите столько методов с тем же именем, сколько хотите, и возьмите каждый тип в качестве аргумента в каждом методе. [Это называется перегрузкой. например Вы, возможно, видели, что +1 Overloads рядом методов, что предполагает, что есть еще один метод с таким же именем, но с разными типами аргументов]

Say Как это:

void Method(decimal d) 
{ 
    //Process Decimal 
} 
void Method(string s) 
{ 
    //Process String 
} 

По умолчанию, это будет найти свой собственный метод по типу.