Comments 92
Что так удивляет в конструкции throw null?
Просто следует помнить, что throw null из C# это совсем не то же самое, что throw NULL из С++. Первое является некорректным выражением и приводит к исключению, второе эквивалентно throw 0.
Просто следует помнить, что throw null из C# это совсем не то же самое, что throw NULL из С++. Первое является некорректным выражением и приводит к исключению, второе эквивалентно throw 0.
+1
UFO just landed and posted this here
Кстате — через «И».
А так спасибо — интересно.
А так спасибо — интересно.
0
Интересно, спасибо.
Правда ИМХО это к собеседованиям как-то мало применимо… Трюки — они трюки и есть.
Правда ИМХО это к собеседованиям как-то мало применимо… Трюки — они трюки и есть.
+1
while (count --> 0)
Это гораздо лучше в целях читаемости кода писать как while (count-- > 0). И, кстати, Визуал Студия сама предлагает такой вариант по умолчанию.
+1
while (count --> 0)
вообще, это дикримент(--) и сравнение(>), по отдельности, а не «странная стрелочка».
ЗЫ меня поначалу смутило :)
+1
IDisposable — креативненько. Не очень представляю реальные сценарии, но забавно.
Насчет throw null — сработает, но стэк поломает, правильно? Это же будет ошибка для throw, которому передали null вместо инстанса исключения. Т.е. это просто вызов одной поломки вместо другой — по сути вы замаскируете ошибку.
Лямбды — а можно пример из реального сценария, как это может использоваться?
Очепятка
«Медоды расширения можно применять не только ...»
Насчет throw null — сработает, но стэк поломает, правильно? Это же будет ошибка для throw, которому передали null вместо инстанса исключения. Т.е. это просто вызов одной поломки вместо другой — по сути вы замаскируете ошибку.
Лямбды — а можно пример из реального сценария, как это может использоваться?
Очепятка
«Медоды расширения можно применять не только ...»
+2
IDisposable я использовал в продашкн под формз до того как познакомился с PostSharp.
throw null — да, должно стек поломать. Не для продакшна — только для быстрого выброса исключения при тестировании.
Лямбды — используется в Fluent NHibernate, например.
throw null — да, должно стек поломать. Не для продакшна — только для быстрого выброса исключения при тестировании.
Лямбды — используется в Fluent NHibernate, например.
0
про IDisposable тут пришло правильное замечание — а если кто использует метод без Using :)
0
ну в таком случае по-хорошему будет вызывать метод Dispose() ручками, что повлечет за собой тот же эффект
0
… Тот сам себе злобный буратино — в .net conventions сказано: «если класс реализует IDisposable, необходимо его использовать через using (или вызвать IDispose) руками».
+4
ээх, ваши слова да 90% программистам в уши…
Если сущность допускает неправильный вызов — она будет неправильно вызвана :)
Если сущность допускает неправильный вызов — она будет неправильно вызвана :)
0
>>если сущность допускает неправильный вызов — она будет неправильно вызвана
Это уже переделка законов Мерфи какая-то :)
Это уже переделка законов Мерфи какая-то :)
0
Вот в Воо можно расширить компилятор чтобы по рукам било. А в шарпе придется терперь…
0
А в шарпе можно бить по рукам злобных буратин, чтобы они учились и совершенствовались — таким образом можно избежать большего числа проблем, чем вводя ограничения компилятора каждый раз. :D
0
Смотря в какой стране идет разработка ;) ИМХО в некоторых локейшнах как раз использование StyleCop, FxCop, maintainability metrics и прочих злостных вещей как раз самое то. Только вот не думаю что они там на Воо пишут ;)
0
Муахаха, для нашей команды самый главный FxCop, NDepend, simian и Gendarme — это я. Меня уже все ненавидят :)
0
Много джуниоров в проекте?
0
Формально — один (я :D)
0
У меня такая же ерунда была, когда джуниором был )
Всем надоел со стилями программирования и именования, борьбой с «оригинальными» подходами в алгоритмах и архитектуре.
Всем надоел со стилями программирования и именования, борьбой с «оригинальными» подходами в алгоритмах и архитектуре.
0
А счас перестали, что ли?
Формально я джуниор, фактически — техлидер/архитектор на 2х проектах, так что тут обратная аналогия — вы в бытность junior всех доставали, я — на подходах к senior developer :)
Формально я джуниор, фактически — техлидер/архитектор на 2х проектах, так что тут обратная аналогия — вы в бытность junior всех доставали, я — на подходах к senior developer :)
0
Это архитипическая проблема нашей индустрии наверное — когда джуниоры намного полезней на проекте чем интермедиаты, сениоры и даже лида. Только в «сервисах» хз как это разруливать ;)
0
Ммм… на текущем месте работы, с которого я ухожу, сложилось хрупкое равновесие — программисты делают вид, что работают, а начальство делает вид, что им верит.
При это заказчик доволен, потому что пилит бюджет, и ему пофиг на качество, ему нужно отчеты о работе: баг исправили, два внесли, но это никого не волнует, главное — процесс.
Говорить о том, что кто-то заинтересован в качестве — я думаю, излишне; я уже писал, что ведущий программист проекта не умеет мержить ветки в репозитории, и отказывается это делать. Unit-тесты прожили ровно 3 месяца, пока я ходил и ругался. Перестал орать — перестали писать и даже запускать. О continuos integration никто и слышать не хочет, просил Фаулера прочитать — куммулятивный ответ таков: «я не буду заниматься этим в свободное время, а на работе мне на это не выделят ресурс».
Junior я тут, потому что на 3 субпроекта — 2 архитектора, 3 тестера + 1 тестлид, 1 менеджер, 1 ведущий программист и 1 mid. Ясно, что тут нужен кто-то, кто будет писать код, а не совещаться по 4 часа в переговорке. А вот тот, кто пишет код — и есть code-monkey, т.е. jun. Доходит до смешного — после коммитов «команды» в репу я вынимаю код и переписываю его :)
*Рамазывает слезы и разговаривает с портретом МакКоннела на обложке* — Но мы же им покажем, правда, Стиви?
При это заказчик доволен, потому что пилит бюджет, и ему пофиг на качество, ему нужно отчеты о работе: баг исправили, два внесли, но это никого не волнует, главное — процесс.
Говорить о том, что кто-то заинтересован в качестве — я думаю, излишне; я уже писал, что ведущий программист проекта не умеет мержить ветки в репозитории, и отказывается это делать. Unit-тесты прожили ровно 3 месяца, пока я ходил и ругался. Перестал орать — перестали писать и даже запускать. О continuos integration никто и слышать не хочет, просил Фаулера прочитать — куммулятивный ответ таков: «я не буду заниматься этим в свободное время, а на работе мне на это не выделят ресурс».
Junior я тут, потому что на 3 субпроекта — 2 архитектора, 3 тестера + 1 тестлид, 1 менеджер, 1 ведущий программист и 1 mid. Ясно, что тут нужен кто-то, кто будет писать код, а не совещаться по 4 часа в переговорке. А вот тот, кто пишет код — и есть code-monkey, т.е. jun. Доходит до смешного — после коммитов «команды» в репу я вынимаю код и переписываю его :)
*Рамазывает слезы и разговаривает с портретом МакКоннела на обложке* — Но мы же им покажем, правда, Стиви?
0
Ситуация знакомая. Естественно что талантливому разработчику там не место. Но с другой стороны, есть очень мало фирм которые в принципе могу саппортить очень прогрессивных начинающих специалистов. Взять ту же заказную разработку — как человека продать подороже и дать зарплату побольше если у него много навыков и талантов, но небольшой послужной список? Заказчик ведь не будет вникать в эти тонкости.
При этом я не хочу сказать что сервисные разработчики чем-то хуже продуктовых. Никак нет! Просто продуктовым легче, потому что профессионализм классного спеца отражается на качестве продукта и тем самым на продажах. В «сервисах», увы, цепочка подлиннее.
При этом я не хочу сказать что сервисные разработчики чем-то хуже продуктовых. Никак нет! Просто продуктовым легче, потому что профессионализм классного спеца отражается на качестве продукта и тем самым на продажах. В «сервисах», увы, цепочка подлиннее.
0
… и чем ближе, тем больше, муаххаха!
0
О IDisposable — таким же образом реализован FileStream.
+1
С IDisposable это использование средств языка не по назначению, соответственно плохой стиль. Нужно писать понятный код, а не рыть ямы на каждом шагу.
0
А я очень часто использую такую конструкцию в UI.
Можно хоть во вложенных методах вызывать. IsLoading станет false только после выполнения самого внешнего using.
Код
private void BeginLoading()
{
IsLoading = true;
}
private void EndLoading()
{
IsLoading = false;
}
protected IDisposable Loading()
{
return new LoadingHelper(this);
}
private class LoadingHelper : IDisposable
{
private readonly BaseViewModel _viewModel;
private readonly bool _wasLoading;
public LoadingHelper(BaseViewModel viewModel)
{
_viewModel = viewModel;
_wasLoading = _viewModel.IsLoading;
if (!_wasLoading)
{
_viewModel.BeginLoading();
}
}
public void Dispose()
{
if (!_wasLoading)
{
_viewModel.EndLoading();
}
}
}
Можно хоть во вложенных методах вызывать. IsLoading станет false только после выполнения самого внешнего using.
0
По мне так это тоже относительно относящиеся к собеседовнию вопросы. Что значит необычное поведение или использование языка?
Я сам постоянно использую конструкции описанные в «Креативное использование Dispose()» для смены настроение Graphics, но не подумал бы что это что-то неординарное.
Что значит полезность оператора _??_? Либо о нем знают либо нет. Что тут необычного?
Лямбды не использую — пишу на 2.0.
В любом случае, каждый приведенный шаблон только с натяжкой можно назвать чем-то необычным. На собеседовании Вы вряд ли соберетесь выдавить из памяти хоть пару чего-то похожего. Потому что по памяти сложно вспоминать то, что и словами то описать сложно.
По мне так самые лучшие вопросы на собеседовании те, которые вообще имеют малое отношение к используемой технологии, если конечно должность не требует ее отменного знания. Например, почему колодцы на улицах круглые, сколько домов в городе. Изходя из логики рассуждение «испытуемого» можно сложить представление подходит он или нет.
А именно по технологии, то вопросов о базовых знаний вполне хватит. Например, сортировать на требуемом языке символы во входящей строке. Вообще, все что может потребоваться от соискателя можно узнать в неформальной обстановке, неформальными вопросами — делел/не делал, где использовал.
Я сам постоянно использую конструкции описанные в «Креативное использование Dispose()» для смены настроение Graphics, но не подумал бы что это что-то неординарное.
Что значит полезность оператора _??_? Либо о нем знают либо нет. Что тут необычного?
Лямбды не использую — пишу на 2.0.
В любом случае, каждый приведенный шаблон только с натяжкой можно назвать чем-то необычным. На собеседовании Вы вряд ли соберетесь выдавить из памяти хоть пару чего-то похожего. Потому что по памяти сложно вспоминать то, что и словами то описать сложно.
По мне так самые лучшие вопросы на собеседовании те, которые вообще имеют малое отношение к используемой технологии, если конечно должность не требует ее отменного знания. Например, почему колодцы на улицах круглые, сколько домов в городе. Изходя из логики рассуждение «испытуемого» можно сложить представление подходит он или нет.
А именно по технологии, то вопросов о базовых знаний вполне хватит. Например, сортировать на требуемом языке символы во входящей строке. Вообще, все что может потребоваться от соискателя можно узнать в неформальной обстановке, неформальными вопросами — делел/не делал, где использовал.
0
> bool b = false && a(); // a() not called
> bool c = false & a(); // a() called
странный пункт. правда я не гуру c#, но по аналогии с другими языками думаю, что приведенные две строки вообще разные по сути. соответсвенно нет ничего удивительного, что для побитового сравнения «a() called», потому что конструкция false & a() возвращает число, а не bool.
> bool c = false & a(); // a() called
странный пункт. правда я не гуру c#, но по аналогии с другими языками думаю, что приведенные две строки вообще разные по сути. соответсвенно нет ничего удивительного, что для побитового сравнения «a() called», потому что конструкция false & a() возвращает число, а не bool.
0
Это специфика C#. Этот вопрос фигурирует на тесте Brainbench. Биты тут как бы не причем.
0
т.е. в C# 2 & 3 != 2?
0
Я имел ввиду для булевых значений.
0
хорошо, спрошу по-другому. если a() возвращает int то, строки:
bool c = false & a();
и
bool c = (bool)( (int)false & a() );
скомпилируются в один и тот же код или нет?
а в случае, если a() возвращает bool?
неужели в c# оператор & компилируется по-разному в зависимости от операндов?
bool c = false & a();
и
bool c = (bool)( (int)false & a() );
скомпилируются в один и тот же код или нет?
а в случае, если a() возвращает bool?
неужели в c# оператор & компилируется по-разному в зависимости от операндов?
0
боюсь (int)false не прокатит ни в какой версии
0
У нас, вообще-то, не С++ а C#, и если написать такой вот тест:
То получите вот такой вот IL:
static bool a() { return true; }
static bool b() { return false; }
static void Main(string[] args)
{
bool c = a() && b();
bool d = a() & b();
}
То получите вот такой вот IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] bool c,
[1] bool d)
L_0000: nop
L_0001: call bool ConsoleSandbox.Program::a()
L_0006: brfalse.s L_000f
L_0008: call bool ConsoleSandbox.Program::b()
L_000d: br.s L_0010
L_000f: ldc.i4.0
L_0010: stloc.0
L_0011: call bool ConsoleSandbox.Program::a()
L_0016: call bool ConsoleSandbox.Program::b()
L_001b: and
L_001c: stloc.1
L_001d: ret
}
0
И не только C#. В PHP то же самое
0
быть может я немного не понимаю о чем речь :)
в PHP:
function a()
{
return 2;
}
$res = true | a(); // $res — int, значение 3
в PHP:
function a()
{
return 2;
}
$res = true | a(); // $res — int, значение 3
0
Простите, а это фишки какой версии .NET`а?
0
Варнинг: ленивая инициализация через ?? в вашем примере потоконебезопасна :) Имхо не стоит сразу учить людей плохому :)
0
Поставил lock(this) и стала потокобезопасной, проблем то.
Не нравится lock — поставил Mutex.
Не нравится lock — поставил Mutex.
0
вообще Mutex это конечно масштабно :) имхо lock'у тут самое место
+1
Так я и не говорю, что проблема :)
Однако lock — тоже «вещь в себе», хорошая тема для собеседований.
Однако lock — тоже «вещь в себе», хорошая тема для собеседований.
+1
Товарищ Джувал Лови учит, что lock(this) можно только для private/internal типов, т.к. иначе нет никаких гарантий, что я например не захочу использовать ваш объект как sync root.
0
жалко что вы в питере:)
0
Делегат-заглушка это здорово.
только ведь этож наверное надо проводить на уровне code convention, иначе один так а дугой по старинке… и привет NullReferenceException
только ведь этож наверное надо проводить на уровне code convention, иначе один так а дугой по старинке… и привет NullReferenceException
0
занятно, но для собеседования также сомнительно. Большинство пунктов показывает знаком человек с «последними» фишками или нет. Над стрелочкой где-то минуту протупил, думал когда этот оператор могли добавить и как его пропустил =)
+3
А вот в Java
throw null именно кидает null
А посему кусок из реального кода
try {
… some code…
} catch (Throwable t) {
try {
t.printStackTrace();
throw t;
} catch (Exception ex) {
ex.printStackTrace();
throw t;
}
}
PS Действительно, люди задают на собеседованиях очень странные и глупые вопросы. И абсолютно не задают то, что действительно важно.
throw null именно кидает null
А посему кусок из реального кода
try {
… some code…
} catch (Throwable t) {
try {
t.printStackTrace();
throw t;
} catch (Exception ex) {
ex.printStackTrace();
throw t;
}
}
PS Действительно, люди задают на собеседованиях очень странные и глупые вопросы. И абсолютно не задают то, что действительно важно.
0
> А вот в Java throw null именно кидает null
Неправда.
JLS 14.18:
Неправда.
JLS 14.18:
If evaluation of the Expression completes normally, producing a null value, then an instance V' of class NullPointerException is created and thrown instead of null.
0
э, я один не увидел здесь ни одного трюка?
-5
bool b = false && a(); // a() not called
bool c = false & a(); // a() called
В любом нормальном языке так и будет работать ибо для логического и не нужно второе значение, если первое 0.
try {
throw null;
} catch (NullReferenceException) {
// will be caught!
}
имхо логично, а что ему еще делать то, а для понимания я бы не стал так делать, а кинул стандартным методом.
public IEnumerable Create(int count)
{
while (count --> 0)
yield return new Foo();
}
имхо закосы под brainfuck не есть гуд, как и написано в описании, это смутит того кто увидит код? а оно тебе надо, это голые понты.
bool c = false & a(); // a() called
В любом нормальном языке так и будет работать ибо для логического и не нужно второе значение, если первое 0.
try {
throw null;
} catch (NullReferenceException) {
// will be caught!
}
имхо логично, а что ему еще делать то, а для понимания я бы не стал так делать, а кинул стандартным методом.
public IEnumerable Create(int count)
{
while (count --> 0)
yield return new Foo();
}
имхо закосы под brainfuck не есть гуд, как и написано в описании, это смутит того кто увидит код? а оно тебе надо, это голые понты.
-1
С последним как раз все нормально, вполне читаемый код. А стрелочка, ну это шутка такая, для поддержания тонуса :) Для тех кому не нравится, есть Visual Basic.
0
Я бы добавил в пункт «Делегат-заглушка», что это поле надо обозначать как несереализуемое, либо клас никогда не должен сериализоваться.
Про «Странная стрелка при перечислении» при первом автоформатировании документа его разорвёт, и вообще это из рода извращений, а их можно очень много привести, например:
protected void TryReadValueType<_>(int index, out @_? @struct)
where _: struct
{
object @object = _command.Parameters[index];
@struct = @object == DBNull.Value? default(@_?): (@_?)@object ?? default(@_?);
}
Приведу от себя несколько полезных вещей:
1) using CounterKeyValue = System.Collections.Generic.KeyValuePair<string, decimal>;
2) Статические поле
public abstract class MyClasswhere T: MyClass{
private static bool _someField = some_value;
}
public class MyClass2: MyClass{
}
public class MyClass3: MyClass{
}
MyClass2 и MyClass3 будут иметь разные статические поля _someField
3) Конструкторы для для хендлеров
Func<int, int, Func> handlerConstructor =
(dx, dy) => () => {
return dx + dy;
};
event1 += handlerConstructor (10, -1);
event2 += handlerConstructor (10, -3);
и др. отвлекаться лень :-)
Про «Странная стрелка при перечислении» при первом автоформатировании документа его разорвёт, и вообще это из рода извращений, а их можно очень много привести, например:
protected void TryReadValueType<_>(int index, out @_? @struct)
where _: struct
{
object @object = _command.Parameters[index];
@struct = @object == DBNull.Value? default(@_?): (@_?)@object ?? default(@_?);
}
Приведу от себя несколько полезных вещей:
1) using CounterKeyValue = System.Collections.Generic.KeyValuePair<string, decimal>;
2) Статические поле
public abstract class MyClasswhere T: MyClass{
private static bool _someField = some_value;
}
public class MyClass2: MyClass{
}
public class MyClass3: MyClass{
}
MyClass2 и MyClass3 будут иметь разные статические поля _someField
3) Конструкторы для для хендлеров
Func<int, int, Func> handlerConstructor =
(dx, dy) => () => {
return dx + dy;
};
event1 += handlerConstructor (10, -1);
event2 += handlerConstructor (10, -3);
и др. отвлекаться лень :-)
0
В примере про статическое поле съелость часть кода хабрапарсером
public abstract class MyClass<T>
where T: MyClass<T>
{
private static bool _someField = some_value;
}
public class MyClass2: MyClass<MyClass2>
{
}
public class MyClass3: MyClass<MyClass3>
{
}
А вообще позже напишу больше трюков какие использую, как появится время.
public abstract class MyClass<T>
where T: MyClass<T>
{
private static bool _someField = some_value;
}
public class MyClass2: MyClass<MyClass2>
{
}
public class MyClass3: MyClass<MyClass3>
{
}
А вообще позже напишу больше трюков какие использую, как появится время.
0
Насчет делегата-заглушки на событиях — интересно, подобное описание никак не помешает сборщику мусора удалить объект, у которого события таким вот образом «проинициализированы»?
0
Интересно, а если в случае try-finally написать, например, x=b(), что вернет функция? В смысле, копируется ли значение x там, где стоит return или в момент настоящего возврата? Подозреваю первое. Или нет?
0
В пункте лямбды вместо строк, есть ошибка. PropertyName описан как экстеншн
public static string PropertyName(this object obj, Expression<Func> p).
а исспользуется как просто метод lblName.DataBindings.Add(PropertyName(() => Name), this, null);
правильно было бы просто написать
public static string PropertyName(Expression<Func> p).
Еще одно небольшое замечание, логичнее писать
lblName.DataBindings.Add(PropertyName(() => lblName. Name), this, null);
т.к. по сути вы используется имя Name из текущего контекста, а не имя свойства объекта lblName для которого добавляете биндинг.
public static string PropertyName(this object obj, Expression<Func> p).
а исспользуется как просто метод lblName.DataBindings.Add(PropertyName(() => Name), this, null);
правильно было бы просто написать
public static string PropertyName(Expression<Func> p).
Еще одно небольшое замечание, логичнее писать
lblName.DataBindings.Add(PropertyName(() => lblName. Name), this, null);
т.к. по сути вы используется имя Name из текущего контекста, а не имя свойства объекта lblName для которого добавляете биндинг.
0
Ага, насколько я помню, для класса нужно написать
this.PropertyName(...)
. Я специально вырезал все излишества чтобы показать только саму суть — а именно то, что передавая выражение, можно выдирать из него текстовую сущность. Я сам не фанат WinForms data binding, если честно.0
в данном контексте this.PropertyName тоже станно смотриться, т.к. вы хотите получить имя свойства объекта lblName.
Для понимания лучше lblName.PropertyName(), хотя это приведет к дублированию кода lblName.PropertyName(() => lblName. Name). С другой стороны это позволит в код экстеншена добать проверку, совпадает ли тип объекта для которого вызываем экстеншен, с типом у которого берем имя свойства.
var memberExpression = p.Body as MemberExpression;
Debug.Assert(memberExpression.Expression.Type == obj.GetType());
Для понимания лучше lblName.PropertyName(), хотя это приведет к дублированию кода lblName.PropertyName(() => lblName. Name). С другой стороны это позволит в код экстеншена добать проверку, совпадает ли тип объекта для которого вызываем экстеншен, с типом у которого берем имя свойства.
var memberExpression = p.Body as MemberExpression;
Debug.Assert(memberExpression.Expression.Type == obj.GetType());
0
Согласен, есть в ваших примерах необычное, но большинство «трюков» проходится на первом курсе в универе и за не знание оных можно схватить незачет )
Например я точно уже видел вот эти фишки:
Операторы | и & против || и &&
Полезный оператор ??
Методы расширения
Возврат значения из try-finally
Делегат-заглушка
Но все равно большое спасибо
Например я точно уже видел вот эти фишки:
Операторы | и & против || и &&
Полезный оператор ??
Методы расширения
Возврат значения из try-finally
Делегат-заглушка
Но все равно большое спасибо
0
интересно где вы видели чтобы на 1 курсе проходили расширения?
0
Sign up to leave a comment.
Трюки языка C#