Конкретный вопрос по С#
От: Kiguinko  
Дата: 10.05.01 23:14
Оценка: -2
Кто пробовал писать в С# функции с дефаултовыми параметрами. В доке сказано, что типа С# как и любой нормальный язык поддерживает необязательные парматеры, пишите типа = <value> и получаете такой параметр, на практике компилятор ругается.
Кинуть примером или сами навояте 5 строчек?
Re: Конкретный вопрос по С#
От: Ярослав Говорунов Украина http://www.helicontech.com
Дата: 11.05.01 21:34
Оценка: -2
K>Кто пробовал писать в С# функции с дефаултовыми параметрами. В доке сказано, что типа С# как и любой нормальный язык поддерживает необязательные парматеры, пишите типа = <value> и получаете такой параметр, на практике компилятор ругается.
K>Кинуть примером или сами навояте 5 строчек?

Поправьте меня, если я не прав.
Насколько я помню в C#, равно как и в .NET вообще нельзя делать параметры по умолчанию (и это описано в документации). Возможно, с последнего раза, как я туда заглядывал там что-то изменилось?
Обусловлено это спецификой работы .NET. Две причины:
1. Подставить параметр на вызываемой стороне нельзя, т.к. .NET, как и СОМ работает на интерфейсах, а интерфейс — контракт, в котором форма вызовов методов строго определена. Значит параметр нельзя опустить.
2. Подставить параметр на вызывающей стороне нельзя, т.к. связь объектов происходит в runtime, а значит, пропадает контроль за версиями. Как сообщить клиенту, что новая версия объекта в качестве параметра по умолчанию теперь ожидает не 1, а 2?
Вместо этого предлагается использовать перегруженные функции. Т.е.:
func(int a, int b)
{
...
}
func(int a)
{
func(a,2);
}
Если синтаксис C# и позволяет указывать параметры по умолчанию (чего я не видел), то это все равно выливается в перегрузку функций, только скрывая это от наших глаз.
WBR,
Yaroslav Govorunov
Re[2]: Конкретный вопрос по С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.05.01 15:42
Оценка:
Вообще-то Kiguinko прав!
В доках есть раздел о дефолтных параметрах в C#, то реально облом!

ЯГ>Обусловлено это спецификой работы .NET. Две причины:

ЯГ>1. Подставить параметр на вызываемой стороне нельзя, т.к. .NET, как и СОМ работает на интерфейсах, а интерфейс — контракт, в котором форма вызовов методов строго определена. Значит параметр нельзя опустить.

По-моему Вы не правы. Уж точно Вы не правы насчет COM-а. В COM-ме есть дефолтные параметры.
Да и в CLR-ных языках сделать, это как рас плюнуть. Дело в том, что информацию о параметрах можно разместить в Reflection-информации (.Net-овском аналоге TLB-х).

При этом конкретный язык может читать ее при компиляции и добавлять значение параметра в MSIL-код.

ЯГ>2. Подставить параметр на вызывающей стороне нельзя, т.к. связь объектов происходит в runtime...


Я и говорю... НЕ в рантайме, а при компиляции.

ЯГ>... а значит, пропадает контроль за версиями. Как сообщить клиенту, что новая версия объекта в качестве параметра по умолчанию теперь ожидает не 1, а 2?


Скомпилированная программа должна работать с теми предположениями (о значении дефолтных параметров) которые были верными на момент компиляции. Если это будет не так, то вероятность вылет будет 90%.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Конкретный вопрос по С#
От: Ярослав Говорунов Украина http://www.helicontech.com
Дата: 13.05.01 18:25
Оценка:
VD>Вообще-то Kiguinko прав!
Я же сразу оговорился, что могу быть не прав. Мое заявление базируется на информации, полученной еще при выходе pre-beta версии. С того момента могло многое измениться.
VD>В доках есть раздел о дефолтных параметрах в C#, то реально облом!
Кстати, а где, если не секрет?

ЯГ>>Обусловлено это спецификой работы .NET. Две причины:

ЯГ>>1. Подставить параметр на вызываемой стороне нельзя, т.к. .NET, как и СОМ работает на интерфейсах, а интерфейс — контракт, в котором форма вызовов методов строго определена. Значит параметр нельзя опустить.

VD>По-моему Вы не правы. Уж точно Вы не правы насчет COM-а. В COM-ме есть дефолтные параметры.

Но они подставляются на вызывающей стороне, насколько я помню.
VD>Да и в CLR-ных языках сделать, это как рас плюнуть. Дело в том, что информацию о параметрах можно разместить в Reflection-информации (.Net-овском аналоге TLB-х).
Именно так это и делается в СОМ.

VD>Я и говорю... НЕ в рантайме, а при компиляции.

Во во. Ключевое слово тут "при компиляции". В то время MS считала, что в .NET не должно быть ничего, что можно сделать только при компиляции.

ЯГ>>... а значит, пропадает контроль за версиями. Как сообщить клиенту, что новая версия объекта в качестве параметра по умолчанию теперь ожидает не 1, а 2?


VD>Скомпилированная программа должна работать с теми предположениями (о значении дефолтных параметров) которые были верными на момент компиляции. Если это будет не так, то вероятность вылет будет 90%.

Я бы привел ссылку, но уже не помню. Давненько я не интересовался как дела у .NET, так что спорить не стану, все могло измениться. В той статье такое поведение объяснялось именно нарушением контроля версий.
Самым лучшим способом проверить — создать на C# метод с параметрами по умолчанию, а потом посмотреть в ildasm. Если будут перегруженные функции, значит дела все еще как и были, если будет запись в Reflection, значит все изменилось...
WBR,
Yaroslav Govorunov
Re[4]: Конкретный вопрос по С#
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.01 12:53
Оценка:
Здравствуйте Ярослав Говорунов, вы писали:

VD>>В доках есть раздел о дефолтных параметрах в C#, то реально облом!

ЯГ>Кстати, а где, если не секрет?
Я включил фильтрацию по C# и сделал поиск по: "default near param*". См. в конце сообщения.

VD>>По-моему Вы не правы. Уж точно Вы не правы насчет COM-а. В COM-ме есть дефолтные параметры.

ЯГ>Но они подставляются на вызывающей стороне, насколько я помню.
Значения параметров всегда задается вызывающей стороной. Дефолтные параметры — тлько оптимизация (упрощение) для программиста.

VD>>Я и говорю... НЕ в рантайме, а при компиляции.

ЯГ>Во во. Ключевое слово тут "при компиляции". В то время MS считала, что в .NET не должно быть ничего, что можно сделать только при компиляции.
Если в тайп-инфо есть значения, то их можно вынуть и в рантайме. Но зачем?

ЯГ>>>... а значит, пропадает контроль за версиями. Как сообщить клиенту, что новая версия объекта в качестве параметра по умолчанию теперь ожидает не 1, а 2?


ЯГ>Самым лучшим способом проверить — создать на C# метод с параметрами по умолчанию, а потом посмотреть в ildasm. Если будут перегруженные функции, значит дела все еще как и были, если будет запись в Reflection, значит все изменилось...

Для того чтобы проверить сначало надо скомпилировать! А этого и не получаестя.


А я ссылки нащел:
Но повторить пример не получилось :(. Межет в бете-2 или в релизе сделают?! Или в хелпе опечатка (

ms-help://MSDNVS/cpref/html_hh2/frlrfSystemReflectionParameterInfoClassDefaultValueImplTopic.htm
ms-help://MSDNVS/cpguide/html_hh2/cpconaccessingdefaultargumentvalues.htm

Вот цитата из последнего файла:

*Accessing Default Argument Values*

Some languages (such as managed extensions to C++ and Microsoft Visual Basic) support the assignment of default values to some arguments. For example, the following is a legitimate C# declaration that has default values for two of the arguments:

void MyMethod (int a, double b = 1.2, int c = 1)
{
if ( a == c) //…
}
Using a parameter attribute, a parameter value can explicitly be requested to be the default value.

Methods whose arguments have default values can be invoked either by specifying exactly which arguments are defaults or by leaving off the trailing default arguments. For example, all of the following are valid calls for MyMethod:

MyMethod (10, 55.3, 12);
MyMethod (10, 1.3); // c == 1
MyMethod (11) // b == 1.2, c == 1
To retrieve the default value of an argument using reflection, you first get a ParameterInfo object for the parameter, and then retrieve the default value using the ParameterInfo.DefaultValue property. If there is no default value, the property will return Value.DBNull when you try to retrieve it.

The following code prints out the default values for MyMethod to the console:

MethodInfo m = t.GetMethod ("MyMethod");
ParameterInfo[] ps = m.GetParameters();

...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Почему в C# нет дефолтных параметров
От: Рек Россия  
Дата: 15.05.03 06:15
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Дефолтные параметры — тлько оптимизация (упрощение) для программиста.



100% согласен.

Я сначала не мог понять почему в С# не стали делать параметров по умолчанию.
Ведь удобно, привычно, и писать код удбно и интерфейс класса сокращается
(вместо 5-ти методов один, но с дефолтными параметрами!)
Но наверное тут всё не спроста...

Чем плохи дефолтные параметры?

Гипотеза: дефолтные параметры — это разновидность магических чисел.

Или по другому: Интерфейс класса формулируется не в терминах методов и свойств, и тп,
а еще и с помощью каких то магических значний. Это значения — часть интерфейса.
Изменять их нельзя — это будет другой интерфейс (другая версия).
А ведь обычно магические числа стараются упрятать поглубже (а лучше совсем без них),
а тут они торчат из самого интерфейса!

— Нет, не годится так.- подумали разработчики C# не стали делать дефолтных параметров.
Re[5]: Конкретный вопрос по С#
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 15.05.03 07:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>ms-help://MSDNVS/cpguide/html_hh2/cpconaccessingdefaultargumentvalues.htm

VD>void MyMethod (int a, double b = 1.2, int c = 1)

Какая версия msdn? В свежей примера на c# нет:

http://msdn.microsoft.com/library/en-us/cpguide/html/cpconaccessingdefaultargumentvalues.asp

При попытке так ниписать вылезает CS0241: Default parameter specifiers are not permitted.

Можно попробовать сделаь то же самое руками. Нужно получить результат:

    .method public static void  MyMethod(int32 a,
                                         [opt] float64 b,
                                         [opt] int32 c) cil managed
    {
      .param [2] = float64(1.2)
      .param [3] = int32(0x00000001)


[opt] — это System.Runtime.InteropServices.OptionalAttribute, а как сделать .param другим способом, кроме закрытого в c#, — непонятно. Что любопытно, при добавлении System.ComponentModel.DefaultValueAttribute заодно получается еще и пустой .param, но это все равно не то.
Re[6]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 15.05.03 12:12
Оценка:
Рек>Гипотеза: дефолтные параметры — это разновидность магических чисел.

Проблема не в магических числах. Проблема в том, что вызывающая сборка не видит, какое значения парамтера по умолчанию. Она просто использует то значение, которое вписано на момент компиляции.
... << RSDN@Home 1.0 beta 6a >>
Re[7]: Почему в C# нет дефолтных параметров
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 15.05.03 12:16
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Проблема не в магических числах. Проблема в том, что вызывающая сборка не видит, какое значения парамтера по умолчанию. Она просто использует то значение, которое вписано на момент компиляции.


С константами та же проблема, но они почему-то есть. Кстати, при позднем связывании через Invoke можно передать Missing.Value, и дефолтное значение подставится на рантайме, но ценой производительности.
Re[8]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 15.05.03 12:23
Оценка:
M>>Проблема не в магических числах. Проблема в том, что вызывающая сборка не видит, какое значения парамтера по умолчанию. Она просто использует то значение, которое вписано на момент компиляции.

DG>С константами та же проблема, но они почему-то есть. Кстати, при позднем связывании через Invoke можно передать Missing.Value, и дефолтное значение подставится на рантайме, но ценой производительности.


Совершенно верно.

Кстати, System.Environment.NewLine, например, не сделан константой. Думаю, они в микрософте стараются явно констант избегать.
... << RSDN@Home 1.0 beta 6a >>
Re[9]: Почему в C# нет дефолтных параметров
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 15.05.03 12:31
Оценка:
Здравствуйте, mihailik, Вы писали:

M>Кстати, System.Environment.NewLine, например, не сделан константой.


Это с расчетом на то, чтобы на юниксовых платформах был корректный newline без перекомпиляции. А вот null вместо параметров и 0/default вместо enum-флагов от версий слабо зависят и не помешали бы.

M>Думаю, они в микрософте стараются явно констант избегать.


Не выйдет, все enums — константы. Да и часто не нужно — TicksPerDay вряд ли изменится в следующей версии.
Re[7]: Почему в C# нет дефолтных параметров
От: Рек Россия  
Дата: 15.05.03 12:59
Оценка:
Здравствуйте, mihailik, Вы писали:

Рек>Гипотеза: дефолтные параметры — это разновидность магических чисел.


M>Проблема не в магических числах. Проблема в том, что вызывающая сборка не видит, какое значения парамтера по умолчанию. Она просто использует то значение, которое вписано на момент компиляции.


И правильно делает.
Решение проблемы в отказе от использования параметров по умолчанию.

Повторюсь — параметры по умолчанию удобны автору класса, но неудобны пользователю.

Кроме того они снижают эффективность кода: часто параметр просто не нужен
но он гоняется (в том числе по сети!) из-за того, что программист поленился
написать пяток лишних методов.

А сколько ифов и другого кода, связаного проверками типа:
"А задал ли пользователь вот этот параметр? Уж не дефолтный ли параметр пришел?"
Исполнения этого кода можно избежать, если дать несколько вариантов метода,
взамен одного универсального. Размер кода увеличится, но работать станет быстрее.
Re[7]: Почему в C# нет дефолтных параметров
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.03 19:09
Оценка: 1 (1)
Здравствуйте, mihailik, Вы писали:

Рек>Гипотеза: дефолтные параметры — это разновидность магических чисел.


M>Проблема не в магических числах. Проблема в том, что вызывающая сборка не видит, какое значения парамтера по умолчанию. Она просто использует то значение, которое вписано на момент компиляции.


Да в вызывющей сборке уже вызов будет. И никаких дефолтных параметров. Они нужны только во время компиляции.

А узнать эти значения проще простого. Например, для первого параметра метода Test класса Class1:
typeof(Class1).GetMethod("Test").GetParameters()[0].DefaultValue
... << RSDN@Home 1.0 beta 7a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Почему в C# нет дефолтных параметров
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.03 19:09
Оценка:
Здравствуйте, Рек, Вы писали:

Рек>Повторюсь — параметры по умолчанию удобны автору класса, но неудобны пользователю.


Это чем же?

Рек>Кроме того они снижают эффективность кода: часто параметр просто не нужен

Рек>но он гоняется (в том числе по сети!) из-за того, что программист поленился
Рек>написать пяток лишних методов.

А ты видел как обычно реализовывются методы имеющие большое количество перегрузок? Уж лучше бы были дефолтные параметры.

Рек>А сколько ифов и другого кода, связаного проверками типа:

Рек>"А задал ли пользователь вот этот параметр?

Ноль. Параметр просто будет иметь некое начальное значение. Иначе проще сделать перегруженную функцию.
... << RSDN@Home 1.0 beta 7a >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: Почему в C# нет дефолтных параметров
От: Рек Россия  
Дата: 16.05.03 06:12
Оценка:
Здравствуйте, VladD2, Вы писали:

Рек>>Повторюсь — параметры по умолчанию удобны автору класса, но неудобны пользователю.

VD>Это чем же?

1. Тем, что интерфейс содержит магические числа (дефортные значения параметров).
Врядли это хороший стиль определения интерфейса.

2. Если надо задать в перемешку дефолтные и не дефолтные значения,
то придётся выучить наизусть эти магические числа и программа будет ими пестреть,
этими NULLами, 0ями и -1цами, ... И т.д. и т.п.

3. Эффективность срадает(см. ниже)


Рек>>Кроме того они снижают эффективность кода: часто параметр просто не нужен

Рек>>но он гоняется (в том числе по сети!) из-за того, что программист поленился
Рек>>написать пяток лишних методов.

VD>А ты видел как обычно реализовывются методы имеющие большое количество перегрузок? Уж лучше бы были дефолтные параметры.


Если делo совсем швах, и колво перегрузок (комбинаций параметров) очень велико,
то можно попробовать использовать передачу параметров в спец структуре.
Заполняешь в стукруре только нужные поля (остальные остаются дефлотными)
и переадёшь это хозяйство методу. (пример — ProcessStartInfo).


Рек>>А сколько ифов и другого кода, связаного проверками типа:

Рек>>"А задал ли пользователь вот этот параметр?

VD>Ноль. Параметр просто будет иметь некое начальное значение. Иначе проще сделать перегруженную функцию.


Вот я про это "иначе" и говорю.
Re[9]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 16.05.03 08:49
Оценка:
VD>А ты видел как обычно реализовывются методы имеющие большое количество перегрузок? Уж лучше бы были дефолтные параметры.

Хм, чем лучше?

Чем грузины
... << RSDN@Home 1.0 beta 6a >>
Re[8]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 16.05.03 08:49
Оценка:
VD>А узнать эти значения проще простого. Например, для первого параметра метода Test класса Class1:
VD>
VD>typeof(Class1).GetMethod("Test").GetParameters()[0].DefaultValue
VD>


Какой-никакой вариант. Хотя, тоже капризный (нужно правильно задать индекс параметра), да и тормозной.
... << RSDN@Home 1.0 beta 6a >>
Re[10]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 16.05.03 08:49
Оценка:
M>>Думаю, они в микрософте стараются явно констант избегать.

DG>Не выйдет, все enums — константы.


И правда. А я почему-то думал, что нет

DG> Да и часто не нужно — TicksPerDay вряд ли изменится в следующей версии.


Хм, что-то мне подсказывает, что TicksPerDay изменится в следующем компьютере.
... << RSDN@Home 1.0 beta 6a >>
Re[11]: Почему в C# нет дефолтных параметров
От: desperado_gmbh http://www.livejournal.com/users/tolstopuz
Дата: 16.05.03 09:01
Оценка:
Здравствуйте, mihailik, Вы писали:

DG>> Да и часто не нужно — TicksPerDay вряд ли изменится в следующей версии.

M>Хм, что-то мне подсказывает, что TicksPerDay изменится в следующем компьютере.

В тике 100 наносекунд. DateTime уже во время создания не подходил для хранения интервалов времени, сравнимых с тактом сегодняшних процессоров, датировки событий до нашей эры и страдал проблемой 10000 года. Для остальных применений он может продержатся еще очеь долго.

Вот в таких случаях устоявшегося дизайна в const, подставляющихся во время компиляции, никакой проблемы нет. Немало и аналогичных ситуаций с дефолтными параметрами.
Re[12]: Почему в C# нет дефолтных параметров
От: mihailik Украина  
Дата: 16.05.03 09:15
Оценка:
Здравствуйте, desperado_gmbh, Вы писали:

DG>Здравствуйте, mihailik, Вы писали:


DG>>> Да и часто не нужно — TicksPerDay вряд ли изменится в следующей версии.

M>>Хм, что-то мне подсказывает, что TicksPerDay изменится в следующем компьютере.

DG>В тике 100 наносекунд.


Ага, точно
Повышаем тебе уровень доверия ещё на пару пунктов
... << RSDN@Home 1.0 beta 6a >>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.