Comments 91
Три замечания.
Замечание первое.
Замечание второе.
Кстати, это — еще один контрпример к первому замечанию.
Замечание третье:
Замечание первое.
Явная имплементация всегда статична. Она не может быть переписана (override) или перекрыта (new) в классах-потомках.Не вполне верно. Явная имплементация по сути может быть переписана в классе-потомке, если тот же самый интерфейс реализовать еще раз. При этом используется другой механизм, нежели override, но результат аналогичен.
interface A { void Foo(); }
class B : A { void A.Foo() {} } // Явная реализация
class C : B, A { void A.Foo() {} } // Аналог overide в виде еще одной явной реализации
Замечание второе.
Явная имплементация всегда приватна (private).В C# — да, явная реализация всегда приватна (точнее, она всегда private virtual sealed). Но статья все-таки называется «Немного об интерфейсах в .Net» — а в других языках этого семейства это не так. Я говорю о MSIL и C++/CLI. В этих языках при реализации интерфейса реализующий метод может иметь любой модификатор доступа и имя:
public interface class A {
void Foo();
};
public ref class B : A {
protected:
virtual void Bar() = A::Foo {}
};
Кстати, это — еще один контрпример к первому замечанию.
Замечание третье:
для foreach необходима имплементация не IList, а IEnumerableНеверно. Для foreach необходимо наличие открытого метода GetEnumerator в классе или в одном из интерфейсов, возвращающего объект или структуру, у которого есть открытые метод bool MoveNext() и доступное для чтения свойство Current. Этот механизм позволяет в некоторых случаях (например, при итерации списков) создавать итератор не в куче, а на стеке.
struct EmptyEnumerable
{
public EmptyEnumerator GetEnumerator() { return new EmptyEnumerator(); }
}
struct EmptyEnumerator
{
public bool MoveNext() { return false; }
public object Current { get { throw new InvalidOperationException(); } }
}
class Test
{
public void Run()
{
foreach (var q in new EmptyEnumerable())
throw new InvalidOperationException();
Console.WriteLine("Hello, world!");
}
}
+32
Для foreach необходимо наличие открытого метода GetEnumerator в классе или в одном из интерфейсов, возвращающего объект или структуру, у которого есть открытые метод bool MoveNext() и доступное для чтения свойство Current. Этот механизм позволяет в некоторых случаях (например, при итерации списков) создавать итератор не в куче, а на стеке.
т.е. при использовании foreach происходит не приведение объекта к интерфейсу IEnumerable, а поиск метода GetEnumerator с помощью рефлексии?
+1
Нет. Происходит поиск метода GetEnumerator на этапе компиляции.
Попробуйте скомпилировать тот код, который я привел, а потом декомпилировать в ildasm, если не понятно что происходит.
Попробуйте скомпилировать тот код, который я привел, а потом декомпилировать в ildasm, если не понятно что происходит.
+10
Поддержу человека. Зря минусов ему наставили, потому что игнорирование наследования от интерфейса действительно вводит в ступор. А на счет создания итератора в стеке, так никто наследования структур от интерфейсов не отменял. Приведенный ниже пример работает отлично. Ну а то, что он без интерфейса может работать, так это, как по мне, большой недочет.
public struct Iterator: IEnumerable
{
public IEnumerator GetEnumerator()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
}
public struct Iterator: IEnumerable
{
public IEnumerator GetEnumerator()
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}
}
-1
обалдеть, еще и заминусовать кто-то успел)я уже отвык от того, что тут минусы лепят просто так
0
Интерфейсы всегда имеют ссылочный тип. Поэтому в данном случае реализовывать интерфейс в структуре имеет мало смысла. Потому что если бы foreach умел работать только интерфейсом, то все равно пришлось бы осуществлять операцию упаковки для этой самой структуры. И не существовало бы способа обойтись без упаковки.
+2
Спасибо за очень интересные замечания!
+2
По форме — англицизмы раздражают, да ещё и приправленные тавтологией — имплементирован/имплементирует/имплементация, генерический вариант и т.п.
По сути — интересное исследование.
По сути — интересное исследование.
0
Спасибо за замечание и за оценку!
Я, к сожалению, очень редко читаю техническую литературу на русском языке и мне сложно подбирать термины. Как было бы Вы написали «имплементация» по-русски? И разве по-русски нет выражения «генерические классы»? Я постараюсь исправить статью, если действительно здесь есть хороший русский термин.
Я, к сожалению, очень редко читаю техническую литературу на русском языке и мне сложно подбирать термины. Как было бы Вы написали «имплементация» по-русски? И разве по-русски нет выражения «генерические классы»? Я постараюсь исправить статью, если действительно здесь есть хороший русский термин.
+1
Имплементация это почти всегда реализация.
+1
Устоявшиеся русские термины:
«Реализация [интерфейса]»
«Обобщенные классы»
«Реализация [интерфейса]»
«Обобщенные классы»
+2
О, спасибо, поправлю статью когда доберусь до работы!
0
«Обобщённые» — не слышал.
«Шаблонные»!
«Шаблонные»!
0
Managed C++ это извращение, которое обычно служит для связки модулей, а не является главным языком проекта, где обычно пишут сложные классы. Вот и наблюдаем коллизии реализаций одного и того же подхода, пришедших из разных миров. Но ведь обе эти реализации по сути предназначены для решения одной задачи, поэтому приём, независимо от реализации, можно обозвать одним словом (с уточнением в редких случаях, когда есть опасность перепутать).
-3
>Как было бы Вы написали «имплементация» по-русски?
На мой взгляд вполне нормальное слово, но есть еще «реализация»
>И разве по-русски нет выражения «генерические классы»?
Такого вообще никогда не слышал :) Или «дженерики» или «обобщения»
— P.S. Я буду обновлять страницу перед отсылкой комментария
На мой взгляд вполне нормальное слово, но есть еще «реализация»
>И разве по-русски нет выражения «генерические классы»?
Такого вообще никогда не слышал :) Или «дженерики» или «обобщения»
— P.S. Я буду обновлять страницу перед отсылкой комментария
+4
имплементация — реализация
генерические — обобщенные
инстанция (это вообще ужас) — экземпляр
Я тоже редко читаю на русском (и использую слово имплементация в устной речи), но если пишешь для русской аудитории, лучше писать корректным языком, как мне кажется.
UPD: не обновил страницу, быстро написали. «Дженерики» тоже использую в устной речи, английские слова всегда почти лучше кальки с них
генерические — обобщенные
инстанция (это вообще ужас) — экземпляр
Я тоже редко читаю на русском (и использую слово имплементация в устной речи), но если пишешь для русской аудитории, лучше писать корректным языком, как мне кажется.
UPD: не обновил страницу, быстро написали. «Дженерики» тоже использую в устной речи, английские слова всегда почти лучше кальки с них
+2
Да, но у меня проблема заключается в том, что я никогда не общаюсь с русской аудиторией.
Я начал изучать информатику в Германии и здесь же закончил университет, поэтому я знаю все термины либо как они были в книгах (на английском), либо как их использовали в своей речи немецкие профессора. Поэтому для меня Implementation, Instanz, Generische Klassen — вполне нормальные слова и выражения. Поэтому я охотно исправляю на более принятые в русском языке термины.
Я начал изучать информатику в Германии и здесь же закончил университет, поэтому я знаю все термины либо как они были в книгах (на английском), либо как их использовали в своей речи немецкие профессора. Поэтому для меня Implementation, Instanz, Generische Klassen — вполне нормальные слова и выражения. Поэтому я охотно исправляю на более принятые в русском языке термины.
0
Я тоже редко читаю на русском (и использую слово имплементация в устной речи), но если пишешь для русской аудитории, лучше писать корректным языком, как мне кажется.
Настолько привык к английским терминам, что на русском часто путаюсь. Например, переопределение/перекрытие/перегрузка/сокрытие — что из этого override, что new?
0
>>И разве по-русски нет выражения «генерические классы»
В русских текстах часто пишут «Generic-классы». Термин «обобщённые классы» не все сходу воспринимают, а слово «генерические» действительно режет глаз. Поэтому разумно оставить соответствующий термин без перевода — и так все поймут что имеется ввиду.
В русских текстах часто пишут «Generic-классы». Термин «обобщённые классы» не все сходу воспринимают, а слово «генерические» действительно режет глаз. Поэтому разумно оставить соответствующий термин без перевода — и так все поймут что имеется ввиду.
0
Имплементация = реализация, например.
По-русски «генерические»? Типичный англицизм от «generic», варианты перевода на данный момент — шаблонный класс, класс-шаблон, обобщенный класс; интересная дискуссия на эту тему есть здесь, в последнем посте (от 2004 г.) есть и ваш вариант в качестве… шутки =)
Microsoft использует перевод «универсальный класс», тоже вполне годный вариант.
По-русски «генерические»? Типичный англицизм от «generic», варианты перевода на данный момент — шаблонный класс, класс-шаблон, обобщенный класс; интересная дискуссия на эту тему есть здесь, в последнем посте (от 2004 г.) есть и ваш вариант в качестве… шутки =)
Microsoft использует перевод «универсальный класс», тоже вполне годный вариант.
0
Вариант «шаблонный класс» лучше не использовать, поскольку в C++/CLI существуют как шаблонные (template), так и обобщенные (generic) классы.
+1
Пожалуй, правильнее всего использовать вариант Microsoft, хотя бы для того, чтобы тебя понимали те, кто читает MSDN на русском. Для тех, кто предпочитает оригинальный MSDN, в скобках указывать оригинальное выражение. В идеале же, после написания статьи, неплохо бы сделать список/словарь многократно использованных переведенных терминов и поместить в начало статьи. Что типа такого —
Универсальный класс — generic class;
Уиниверсальный тип — generic type;
…
Наверное, такой подход был бы максимально удобен читателю.
Универсальный класс — generic class;
Уиниверсальный тип — generic type;
…
Наверное, такой подход был бы максимально удобен читателю.
0
Лично мне бы во время чтения мешали лишние упоминания в скобках. А список терминов в конце статьи помог бы мало — я же её уже прочел. Прыгать туда-сюда во время чтения не очень хорошо
0
Пожалуй, правильнее всего использовать вариант Microsoft
Мелкомягких за их автоматические переводы иногда хочется взять и у**ать. Они такие хитровы**анные термины выдумывают, что в жизни не догадаешься, что имелось в виду. Чего стоит перевод attached properties, например… Если в статье будут употребляться мелкомягкие «термины», то я её читать смогу с большим трудом.
+1
Меня тоже немного покоробило.
У нас для интерфейсов используется «Реализация», для Generic — «Обобщенные» или «Типизированные».
P.S.:
К нам пришел новый тестировщик, и каждый раз когда он говорит что-то вроде «Бага репродьюсится» — так и хочется запустить в него чем-нибудь тяжелым.
У нас для интерфейсов используется «Реализация», для Generic — «Обобщенные» или «Типизированные».
P.S.:
К нам пришел новый тестировщик, и каждый раз когда он говорит что-то вроде «Бага репродьюсится» — так и хочется запустить в него чем-нибудь тяжелым.
0
Давайте все же не будем придираться к словам. Ну написал человек как написал, все же прекрасно поняли смысл текста. Между прочим, тут часто встречаются фразы в стиле: «Полазив по сайтам, появилась идея...». Это в принципе неграмотно, т.к. отсутствует связь между частями предложения. Правильный вариант «Полазив по сайтам, мы придумали...». Ну и т.п.
0
Спасибо за тёплые слова!
Поскольку у меня с русским языком, как у многих «технарей», еще со школы было все просто ужасно, я рад что по крайней мере меня понимают и буду стараться расширять свой словарный запас и русской технической лексикой.
Поскольку у меня с русским языком, как у многих «технарей», еще со школы было все просто ужасно, я рад что по крайней мере меня понимают и буду стараться расширять свой словарный запас и русской технической лексикой.
0
Ну здесь же речь о терминологии, а не о русском языке. И на специализированном сайте это весьма актуальная проблема.
Ничего личного против автора не имею, сама статья дала пищу для размышлений.
Ничего личного против автора не имею, сама статья дала пищу для размышлений.
0
Спасибо за статью — хотя я бы сделал ещё упор немного на другое:
Для меня тоже было откровением, что
Однако чуда не произошло: хоть массив и реализует этот интерфейс — все методы списка (
Так что не понятно, зачем такая реализация вообще нужна. Если я передаю в метод параметр типа
Для меня тоже было откровением, что
array
реализует интерфейс IList
. Ведь IList
— это в первую очередь методы Add()
и Remove()
. Поэтому логично было ответить, что array
не реализует интерфейс IList
. Однако чуда не произошло: хоть массив и реализует этот интерфейс — все методы списка (
Add()
, Clear()
, Remove()
, RemoveAt()
, Insert()
) им не поддерживаются. Так что не понятно, зачем такая реализация вообще нужна. Если я передаю в метод параметр типа
IList<>
, то очевидно, что я хочу в этом методе использовать методы специфичные именно для этого интерфейса (в противном случае я бы использовал параметр IEnumerable<>
). А так получается есть возможность без проверки передать массив в качестве такого параметра, чтобы потом в рантайме вылезла ошибка NotSupportedException
.+1
IList — это в первую очередь доступ к элементам по индексу, и массив его поддерживает.
А те методы, которые вы перечислили — это методы списка переменного размера, которым массив не является.
Загляните в документацию (в msdn, например):
А те методы, которые вы перечислили — это методы списка переменного размера, которым массив не является.
Загляните в документацию (в msdn, например):
Представляет коллекцию объектов, доступ к которым может быть получен отдельно, по индексу.Где здесь вообще сказано про изменяемость? Все изменяющие методы — опциональны.
+4
Да, Вы не первый, у кого возникает такой вопрос — у меня он тоже возник в процессе моего исследования.
Лучше всего на него, по-моему, отвечает John Skeet в одном из своих ответов на StackOverflow. Также мне интересным показался и вот этот вопрос, и особенно статья, на которую там дана ссылка.
Лучше всего на него, по-моему, отвечает John Skeet в одном из своих ответов на StackOverflow. Также мне интересным показался и вот этот вопрос, и особенно статья, на которую там дана ссылка.
+1
Советую почитать C# in Depth за авторством Джона Скита. Там очень многие вопросы из приведенных в статье\комментариях рассматриваются и ваш конкретно расписан очень подробно.
+2
UFO just landed and posted this here
Спасибо, буду считать это комплиментом и надеяться дорасти когда-нибудь до таких корифеев, как Рихтер или Трёлсен. :)
+3
Желаю удачи в профессиональном росте! Только имейте ввиду, что «Troelsen» в русском варианте пишется как «Троелсен».
0
Советую задумался о заучивании книги «CLR via C#» Джеффри Рихтера. Там все эти вопросы и еще много много других освещены подробно.
+1
Вообще mayorovp все уже отметил, но вот обычно в реализациях компилятора, когда он встречает forach и мы имеем массив, то там идет оптимизация и на выходе мы будем иметь for (var i = 0; i < array.Length; i++). Такая оптимизация есть и в Mono и в Microsoft .NET. Поэтому, в большинстве случаев, вызова GetEnumerator у массива не будет.
+1
Можно подкрепить источниками?
0
В книге C# in Depth, которую я упоминал выше, так написано, считаю надежным источником. К тому же какие проблемы скомпилить foreach для int[] и List<int> и посмотреть дизассемблированный код? Я проверил — в IL для первого случая вызовов GetEnumerator и проч. нету, для второго — есть.
0
А тут не нужны источнки, скачайте моно. И скомпилируйте 2 цикла с foreach и for, и посмотрите IL код. Тело цикла будет совпадать в обоих случаях (также и для Microsoft.NET). Конечно в блоге разработчиков где-то есть описание но искать лень.
0
Допустим у нас есть следующий код:
Скомпилируем его:
Первый цикл:
Второй цикл:
Третий цикл:
using System;
using System.Linq;
namespace TestArrayInForeach
{
class Program
{
static void Main(string[] args)
{
var array = args.Select(int.Parse).ToArray();
var arrayLength = array.Length;
// First case
for (var index = 0; index < array.Length; index++)
{
Console.WriteLine(array[index]);
}
// Second case
foreach (int item in array)
{
Console.WriteLine(item);
}
// Third case
for (var index = 0; index < arrayLength; index++)
{
Console.WriteLine(array[index]);
}
}
}
}
Скомпилируем его:
Первый цикл:
{
Console.WriteLine(array[index]);
00000092 mov eax,dword ptr [ebp-8]
00000095 mov edx,dword ptr [ebp-1Ch]
00000098 cmp eax,dword ptr [edx+4]
0000009b jb 000000A2
0000009d call 79033254
000000a2 mov ecx,dword ptr [edx+eax*4+8]
000000a6 call 048F4D90
for (var index = 0; index < array.Length; index++)
000000ab inc dword ptr [ebp-8]
000000ae mov eax,dword ptr [ebp-8]
000000b1 mov edx,dword ptr [ebp-1Ch]
000000b4 cmp eax,dword ptr [edx+4]
000000b7 jl 00000092
Второй цикл:
000000c7 mov eax,dword ptr [ebp-14h]
000000ca mov edx,dword ptr [ebp-20h]
000000cd cmp eax,dword ptr [edx+4]
000000d0 jb 000000D7
000000d2 call 79033254
000000d7 mov eax,dword ptr [edx+eax*4+8]
000000db mov dword ptr [ebp-0Ch],eax
{
Console.WriteLine(item);
000000de mov ecx,dword ptr [ebp-0Ch]
000000e1 call 048F4D90
000000e6 inc dword ptr [ebp-14h]
foreach (int item in array)
000000e9 mov eax,dword ptr [ebp-14h]
000000ec mov edx,dword ptr [ebp-20h]
000000ef cmp eax,dword ptr [edx+4]
000000f2 jl 000000C7
}
Третий цикл:
{
Console.WriteLine(array[index]);
000000fc mov eax,dword ptr [ebp-10h]
000000ff mov edx,dword ptr [ebp-1Ch]
00000102 cmp eax,dword ptr [edx+4]
00000105 jb 0000010C
00000107 call 79033254
0000010c mov ecx,dword ptr [edx+eax*4+8]
00000110 call 048F4D90
for (var index = 0; index < arrayLength; index++)
00000115 inc dword ptr [ebp-10h]
00000118 mov eax,dword ptr [ebp-10h]
0000011b cmp eax,dword ptr [ebp-4]
0000011e jl 000000FC
+1
Подозреваю что там всё хитро. Не влезая в IL провел несколько тестов производительности For и Foreach.
Оказалось следующее: если скомпилировать в Release следующий код:
то время выполнения идентично (гуляет на 0.3%).
если же написать так:
то код стабильно выполняется быстрее, чем foreach, где-то на 3%.
Оказалось следующее: если скомпилировать в Release следующий код:
int s = 0;
for (int z1 = 0; z1 < array.Lenght; z1++)
{
s += array[z1];
}
и foreach (var i in array)
{
s += i;
}
то время выполнения идентично (гуляет на 0.3%).
если же написать так:
int c = array.Length;
for (int z1 = 0; z1 < c; z1++)
{
s += array[z1];
}
то код стабильно выполняется быстрее, чем foreach, где-то на 3%.
0
Провел небольшое исследование…
Код до компиляции:
Код после декомпиляции:
Действительно, компилятор C# считает длину массива переменной…
Код до компиляции:
foreach (var y in x)
Console.WriteLine(y);
Код после декомпиляции:
int[] array = x;
for (int i = 0; i < array.Length; i++)
{
int y = array[i];
Console.WriteLine(y);
}
Действительно, компилятор C# считает длину массива переменной…
0
Он так не считает, просто его не правильно понимаете, он не будет каждый раз дёргать метод array.get_Length
+2
Тесты, приведенные выше, показали — если сохранить длину массива в переменную и использовать в цикле for значение переменной, а не array.Lenght, то такой код стабильно на 3% быстрее. Мелочь, но всё же…
Да и как это, спрашивается, for не будет каждый раз дергать — попробуйте в цикле поменять значение второй переменной из цикла for — на каждом цикле значение этой переменной вычисляется заново.
Да и как это, спрашивается, for не будет каждый раз дергать — попробуйте в цикле поменять значение второй переменной из цикла for — на каждом цикле значение этой переменной вычисляется заново.
0
Я так думаю, что если у вас в цикле что-нибудь более-менее комплексное, то разница будет неощутима. Если же цикл легкий и короткий, то в некоторых случаях его можно переписать на LINQ для читабельности и меньшей вероятности ошибиться в индексах. В большинстве случаев от C# не требуется сверхвысокой производительности и такие вещи как вынос Length в переменную могут только затруднить чтение кода.
0
Так ведь вопрос не в этом. Дело в том, что если уж компилятор автоматически преобразует foreach в for, то надо было бы делать это оптимально — ведь именно оптимальности ждут от оптимизаций.
0
Это с одной стороны. А с другой будет увеличение времени компиляции и размера сборки. Как мне кажется, все сделано правильно. Хочешь мегапроизводительность в мелочах — пиши в стиле C. А если нет — используй foreach. Зачем все усложнять?
0
А с другой будет увеличение времени компиляции и размера сборки.
Где увеличение? Как?!
Увеличение на 10 байт и 100 наносекунд (беру с сильным запасом) — это так много?
0
Где-то столько же вы и выиграете в ран-тайме. А на генерацию локальной переменной по идее все-таки время нужно, нужно же обеспечить уникальность имени — значит, нужно проверять область видимости. Если использовать недопустимые для языка символы в идентификаторе (но допустимые для IL) — тогда нужно проверять и уникальность на случай если несколько циклов в одной области видимости. И даже если их генерировать с циферкой на конце без проверок — на генерацию потребуется время как ни крути и, я так подозреваю, больше, чем 100 наносекунд. Плюс этот код вносит сложность в дальнейшую разработку компилятора. На написание, отладку и тестирование нужно время. Не факт, что руководящие одобрили бы затрату ресурсов на такие мелочи.
Вы не думайте, что я не согласен с тем, что можно было бы сделать как вы предлагаете, я лишь говорю что нет ничего страшного в том, что так сделано не было. Я считаю, они знали о такой возможности, но по своим причинам пошли по пути наименьшего сопротивления.
Вы не думайте, что я не согласен с тем, что можно было бы сделать как вы предлагаете, я лишь говорю что нет ничего страшного в том, что так сделано не было. Я считаю, они знали о такой возможности, но по своим причинам пошли по пути наименьшего сопротивления.
-1
1. Цитата из моего комментария «если скомпилировать в Release следующий код». Само собой, что в DEBUG и под отладкой цифры совсем другие.
2. Внимательнее посмотрите код циклов — они все 3 разные.
2.1 Цикл for от 0 до array.Lenght
2.2 Цикл foreach по элементам array
2.3 Цикл for от 0 до значения локальной переменной, в которую предварительно записали значение array.Lenght
а Выше показан результат декомпиляции 1 foreach и двух идентичных циклов for
2. Внимательнее посмотрите код циклов — они все 3 разные.
2.1 Цикл for от 0 до array.Lenght
2.2 Цикл foreach по элементам array
2.3 Цикл for от 0 до значения локальной переменной, в которую предварительно записали значение array.Lenght
а Выше показан результат декомпиляции 1 foreach и двух идентичных циклов for
0
Если внимательно посмотреть третий цикл, то видно, что for (var index = 0; index < arrayLength; index++), в переменной arrayLength нет точки. Переменная создается до цикла.
Во вторых там я хотел показать именно в том примере, что циклы используют индекс, а не через GetEnumerator, поэтому и запостил там, а не тут. Ну и разницы между двумя for вообще никакой нет. Да, foreach немного по другому скомпилировалось на 6 байт больше в том случае, но это ни разу не показатель в таких синтетических тестах.
Во вторых там я хотел показать именно в том примере, что циклы используют индекс, а не через GetEnumerator, поэтому и запостил там, а не тут. Ну и разницы между двумя for вообще никакой нет. Да, foreach немного по другому скомпилировалось на 6 байт больше в том случае, но это ни разу не показатель в таких синтетических тестах.
0
Единственным способом выявления таких реализаций является использование рефлексии, например при помощи Object Browser в Visual Studio.
По-моему проще посмотреть в MSDN )
По-моему проще посмотреть в MSDN )
0
Ну это сработает только для стандартных классов .Net.
А для решения этой проблемы «в общем» приходится использовать какой-то тул с поддержкой рефлексии, самый простой из них — Object Browser.
А для решения этой проблемы «в общем» приходится использовать какой-то тул с поддержкой рефлексии, самый простой из них — Object Browser.
0
Самый простой — посмотреть исходный код. Если его нет — студия восстановит что сможет из метаданных. Получается гораздо нагляднее, чем Object Browser. По крайней мере, для меня.
0
Понятно, что исходный код — самое лучшее из решений. Но для обзора API все-таки лучше подходят какие-то инструменты вроде Reflector.Net.
А по поводу восстановление класса из метаданных — я не совсем уверен, что это работает во всех версиях…
А по поводу восстановление класса из метаданных — я не совсем уверен, что это работает во всех версиях…
0
Класс из метаданных не восстановится никак.
Но у .NET открыты исходники. И студия умеет их выкачивать и показывать.
А «инструменты вроде Reflector.Net.» — это декомпиляторы.
Но у .NET открыты исходники. И студия умеет их выкачивать и показывать.
А «инструменты вроде Reflector.Net.» — это декомпиляторы.
0
Всегда удивляло, зачем работодатели требуют знания таких вещей наизусть когда есть документация. Разве что на случай если Интернет отключат… Можно, конечно, использовать как косвенный индикатор опыта, но по-моему единственная проверка, что имеющая смысл при найме программиста — пара практических тестовых заданий (например на реализацию и на дебаг) с последующим анализом качества кода, при этом как и в реальных условиях у человека в «дано» должна быть полноценная IDE (в случае C# — актуальная VisualStudio) и свободный доступ в Интернет. Если только это не набор программистов в экипаж, отправляющийся на Марс…
+1
Массивы и цикл foreach — это базовые части языка, их нужно знать без документации.
+1
Ну это было второе (из трех) собеседований, причем оно состояло из трех частей:
1. Письменного теста (вот оттуда этот пример).
2. Теста на компьютере (написать в Visual Studio сначала набор unit tests для метода, рассчитывающего медиану, а потом и запрограммировать этот метод).
3. Устное собеседование с двумя Senior Developers.
Каждая часть длилась по часу. По мне — так вполне адекватно для первой части: проверки на «вшивость», знаешь ли ты вообще, что такое цикл и .Net.
1. Письменного теста (вот оттуда этот пример).
2. Теста на компьютере (написать в Visual Studio сначала набор unit tests для метода, рассчитывающего медиану, а потом и запрограммировать этот метод).
3. Устное собеседование с двумя Senior Developers.
Каждая часть длилась по часу. По мне — так вполне адекватно для первой части: проверки на «вшивость», знаешь ли ты вообще, что такое цикл и .Net.
0
Т.е. если неправильно ответить на этот вопрос, то ты не знаешь, что такое цикл? :)
Я точно знаю и использовал foreach для int[], но не задумывался, реализует ли он IList.
Я точно знаю и использовал foreach для int[], но не задумывался, реализует ли он IList.
0
Ну, там было в тесте три разных раздела (базовые вещи, .Net и базы данных), в каждом по 30-35 вопросов и все на один час. Я не думаю, что неправильный ответ тут сразу бы привел к дисквалификации, скорее вызвал бы удивление, если все остальное было бы неправильно.
В общем и целом я думаю, учитывается совокупность факторов, и тот факт, что все это делается в стрессовых условиях.
В общем и целом я думаю, учитывается совокупность факторов, и тот факт, что все это делается в стрессовых условиях.
0
Покажусь снобом, или ещё кем-нибудь плохим, но не зная про требование foreach к классу, про массив и IList, про то где находится Count, вам не стоило упоминать про Senior .Net Developer. Это просто смешно. Такие вещи знают обычно Junior'ы с годом опыта которые прочли пару книжек по C#/.NET
+1
О, как я ждал этого комментария! :)
Действительно, Вы покажетесь снобом или «кем-нибудь плохим», особенно учитывая тот факт, что на работу меня взяли (да, именно Senior Developer).
Вы, конечно, это тоже все знали после года работы Junior и прочтения «пары книжек» по .Net, не так ли?
«Это просто смешно».
Действительно, Вы покажетесь снобом или «кем-нибудь плохим», особенно учитывая тот факт, что на работу меня взяли (да, именно Senior Developer).
Вы, конечно, это тоже все знали после года работы Junior и прочтения «пары книжек» по .Net, не так ли?
«Это просто смешно».
0
Я, к примеру, знал, еще не имея года коммерческой разрабоки на .NET, а только just4fun, в рамках курсовых и лабораторных. Да и джуниором я никогда не был в общепризнаном понимании. Книжек я не читал. Да и формальное название роли никакого отношения к реальности не имеет.
PS: сколько Senior .NET Developer зарабатывает в Германии?
PS: сколько Senior .NET Developer зарабатывает в Германии?
0
И что же Вы знали?
.NET Senior Developer зарабатывает столько, на сколько он сможет договориться :)
.NET Senior Developer зарабатывает столько, на сколько он сможет договориться :)
0
Знал то, про что выше написал GrigoryPerepechko.
.NET Senior Developer зарабатывает столько, на сколько он сможет договориться :)Извините, но это чушь.
0
> Знал то, про что выше написал GrigoryPerepechko.
Ну, то что он выше написал я тоже, честно говоря, не понял — что конкретно он имеет в виду. Поэтому мне было интересно, что конкретно Вы знали, разрабатывая just4fun.
Я спрашиваю потому, что я собственно не только работаю много лет как разработчик, я и преподаю .Net как MCT и те же Collections входят в базовый курс .Net (раньше экзамен 70-536), который я преподавал несколько раз как тренер. Но утверждать, что это всё знают junior и в рамках собеседования легко ответят не все это, особенно в той патетичной манере, как это изложено — честно скажу, не верю. Как говорится «на миру и смерть красна» — легко заявлять о чем-то, когда ты сидишь в браузере и печатаешь комментарий…
По поводу зарплат — что Вас не устраивает? В Германии нет тарифной сетки для работающих в частных структурах, поэтому зарплата Senior Developer полностью зависит от того, насколько он договорится с работодателем — и эта зарплата может колебаться в 2-3 раза в зависимости от фирмы, земли и места работы…
Ну, то что он выше написал я тоже, честно говоря, не понял — что конкретно он имеет в виду. Поэтому мне было интересно, что конкретно Вы знали, разрабатывая just4fun.
Я спрашиваю потому, что я собственно не только работаю много лет как разработчик, я и преподаю .Net как MCT и те же Collections входят в базовый курс .Net (раньше экзамен 70-536), который я преподавал несколько раз как тренер. Но утверждать, что это всё знают junior и в рамках собеседования легко ответят не все это, особенно в той патетичной манере, как это изложено — честно скажу, не верю. Как говорится «на миру и смерть красна» — легко заявлять о чем-то, когда ты сидишь в браузере и печатаешь комментарий…
По поводу зарплат — что Вас не устраивает? В Германии нет тарифной сетки для работающих в частных структурах, поэтому зарплата Senior Developer полностью зависит от того, насколько он договорится с работодателем — и эта зарплата может колебаться в 2-3 раза в зависимости от фирмы, земли и места работы…
0
По поводу зарплат — что Вас не устраивает? В Германии нет тарифной сетки для работающих в частных структурах, поэтому зарплата Senior Developer полностью зависит от того, насколько он договорится с работодателем — и эта зарплата может колебаться в 2-3 раза в зависимости от фирмы, земли и места работы…От земли — может быть. Остальное ерунда, т.к. зарплата полностью подчиняется закону рынка. И, таким образом, при условии, что «Senior Developer» это некий стандарт, то все такие программисты со временем будут работать в одном месте — там где зарплата в 3 раза выше. Либо везде будет примерно одинаковая зарплата.
я и преподаю .Net как MCTТогда я не понимаю, как вы могли не знать, что Array реализует IList`1, что Count это свойство ICollection`1 и ICollection, и про explicit interface implementation? — Про это и пишет GrigoryPerepechko
0
> Остальное ерунда, т.к. зарплата полностью подчиняется закону рынка. И, таким образом, при условии, что «Senior Developer» это некий стандарт, то все такие программисты со временем будут работать в одном месте — там где зарплата в 3 раза выше.
А уже несколько раз пытаюсь Вам сказать, что это — не «некий стандарт», это скорее описание позиции, где (практически) с первого дня ожидается работа над продуктивным кодом и где никто не настроен сначала тебя обучать тем технологиям, с которыми нужно работать. Поэтому Senior Developer получает столько, насколько он договорился в интервью. Неужели Вы никогда не видели вакансии «зарплата по результатам собеседования»?
>Тогда я не понимаю, как вы могли не знать, что Array реализует IList`1, что Count это свойство ICollection`1 и ICollection, и про explicit interface implementation?
Наверное если бы меня целенаправленно спросили об этом, я бы подумав восстановил всю структуру наследования коллекций и их интерфейсов в голове — но вопрос был поставлен по-другому и это был один из 90 (!) вопросов на которые я должен был ответить в течение часа.
Тем не менее, даже формально когда-то заучив это для сертификаций и преподавания я, честно признаюсь, не понимал что речь в данном случае идет о explicit implementation, и именно осознание этого факта показалось мне достаточно интересным для статьи.
Вы же утверждаете, что для Вас это все было обыденным знанием и все наследование Вы всегда можете его воспроизвести «от зубов»?
А уже несколько раз пытаюсь Вам сказать, что это — не «некий стандарт», это скорее описание позиции, где (практически) с первого дня ожидается работа над продуктивным кодом и где никто не настроен сначала тебя обучать тем технологиям, с которыми нужно работать. Поэтому Senior Developer получает столько, насколько он договорился в интервью. Неужели Вы никогда не видели вакансии «зарплата по результатам собеседования»?
>Тогда я не понимаю, как вы могли не знать, что Array реализует IList`1, что Count это свойство ICollection`1 и ICollection, и про explicit interface implementation?
Наверное если бы меня целенаправленно спросили об этом, я бы подумав восстановил всю структуру наследования коллекций и их интерфейсов в голове — но вопрос был поставлен по-другому и это был один из 90 (!) вопросов на которые я должен был ответить в течение часа.
Тем не менее, даже формально когда-то заучив это для сертификаций и преподавания я, честно признаюсь, не понимал что речь в данном случае идет о explicit implementation, и именно осознание этого факта показалось мне достаточно интересным для статьи.
Вы же утверждаете, что для Вас это все было обыденным знанием и все наследование Вы всегда можете его воспроизвести «от зубов»?
0
Вы же утверждаете, что для Вас это все было обыденным знанием и все наследование Вы всегда можете его воспроизвести «от зубов»?Я этого нигде не утверждал.
Тем не менее, даже формально когда-то заучив это для сертификаций и преподавания я, честно признаюсь, не понимал что речь в данном случае идет о explicit implementation, и именно осознание этого факта показалось мне достаточно интересным для статьи.Это элементарно, Ватсон.
1. То что Array реализует IList`1 _должно_ быть известно всем, т.к. с массивами и всякими списками все работают постоянно.
2. У IList`1 где-то в иерархии есть поле Count.
3. У Array этого поля нет.
4. Следовательно: оно было реализовано через explicit implementation, т.к. нельзя оставлять члены интерфейса без реализации.
Тем не менее, даже формально когда-то заучив это для сертификаций и преподавания я, честно признаюсь, не понимал что речь в данном случае идет о explicit implementation, и именно осознание этого факта показалось мне достаточно интересным для статьи.В этом и проблема: вы их заучили, а я это знаю, потому что с этим работаю.
Неужели Вы никогда не видели вакансии «зарплата по результатам собеседования»?Не знаю как у вас в Германии, а в России за этой фразой обычно прячут неприлично низкую зарплату. У кого высокие зарплаты — не скрывают суммы.
А уже несколько раз пытаюсь Вам сказать, что это — не «некий стандарт», это скорее описание позиции, где (практически) с первого дня ожидается работа над продуктивным кодом и где никто не настроен сначала тебя обучать тем технологиям, с которыми нужно работать.
Поэтому Senior Developer получает столько, насколько он договорился в интервью.1. Я прекарсно осознаю что значит Senior .NET Developer. 2. Между первой и второй фразой нет никакой связи. 3. Работодатель заранее знает, сколько он будет платить кандидату — так называемая «вилка».
0
Просвятите, как это сакральное знание помогает сеньору в работе?
0
>Чтобы получить доступ к имплементации необходимо кастовать инстанцию класса к интерфейсу
доставило.
доставило.
+2
Sign up to leave a comment.
Немного об интерфейсах в .Net (по мотивам одного интервью)