Pull to refresh

Comments 26

укажите, что это .net 3.0+

и ещё.. вам религия не позволяет пользоваться direct-cast вместо as?
Не ясно только при чем тут asp.net, или просто потом будет развитие темы? :)
Я бы еще использовал другие виды исключений и добавил бы шаблонный тип в методе Get, что бы потом не приводить к нужному типу конечный результат.
Что то типа этого:

public static T GetValue<T>(this MemberInfo p_member, object obj)
{
if (p_member == null)
throw new InvalidOperationException("Объект не инициализирован");
if (obj == null)
throw new ArgumentNullException("obj");
switch (p_member.MemberType)
{
case MemberTypes.Field:
return (T)(p_member as FieldInfo).GetValue(obj);
case MemberTypes.Property:
return (T)(p_member as PropertyInfo).GetValue(obj, null);
default:
throw new InvalidCastException("Не совместимый тип MemberTypes");
}
}

Но это так, мелкие замечания "на любителя" :)
В начале статьи я написал что и как. Мне хотелось бы выложить несколько статей по созданию полезных базовых классов для страниц в asp.net. Там всюду используются атрибуты, поэтому первая статья типа вводной для описания одного из инструментов.
В остальном: хорошее предложение! Спасибо :) По слову "шаблоны" в вас сразу можно определить бывалого C++ программера, я прав? Generics переводят обычно как "обобщения".
Я не бывалый С++ программист - это просто влияние терминологии во время обучения в университете :)
А почему бы вместо анализа свойста MemberType не сделать перегрузки, которые будут принимать FieldInfo или PropertyInfo?
Тогда не для FieldInfo или PropertyInfo мы не получим Exception ;)
P.S. Это только мое предположение, а так предложение тоже хорошее.
А зачем? Зачем создавать еще два статических метода? Поясните вашу мысль, может быть я что-то не улавливаю. Что ваше предложение даст?
Я не совсем правильно выразился. Надо заменить методы на два перегруженных. Чтобы, например, для ConstructorInfo (который тоже наследник MemberInfo) Intellisense не показывал методы GetValue и SetValue.
Спасибо за интересный пост. Проблему понял. Сейчас посмотреть не могу, но скоро отпишу...
Нежелательное наследование extension метода - это, оказывается, серьезная проблема. Я потратил примерно два часа на поиски в интернете и не нашел решения. Похоже, скрыть extension method для потомков невозможно. Если вам или кому-то еще известен способ написать такой метод и скрыть его от потомков класса, очень прошу написать мне.
А можно узнать, зачем такое вообще понадобилось?
Простите, вы в работе это использовали? Сообщение об ошибке типа "недопустимые параметры" или "Не совместимый тип MemberTypes" _ничего_ не говорит о ее источнике. Добавление одного слова в сообщение не займет много времени, зато сэкономит его потом.

Потенциально опасные вызовы типа (X as Y).Z(). А что если X не приведется к Y?

И присоединяюсь к вопросу - зачем такое вообще понадобилось? Вы так интенсивно пользуетесь рефлекшеном?
В данном контексте они не опасны просто потому что проверяется p_member.MemberType. Если же все же возникнет такая интересная ситуация когда MemberType будет содержать одно, а объект другое, то это уже проблема дургого характера.
Про "понадобилось" я уже объяснял и в самом топике и ниже в комментариях.
А считаете что прямой каст сильно лучше чем as - при неприводимости типов - первый сразу выкидывает исключение, второй - возвращает нулл.

В некоторых местах это бывает критично (особенно на поддержке черте-как написанного кода), и гораздо дешевле проверить результат на нулл чем поместить все в try-catch, не согласны ?
Вообще - зачем создавать себе изначально "потенциально опасные вызовы" - всякие цепочки вида a.x().y().z().b().c() - неудобны ни с точки зрения читабельности, ни с точки зрения надежности кода. ИМХО - не стоит так писать. Тем более в такой конструкции прийдется лазить и смотреть какие исключения может выкинуть каждый элемент цепочки, что может вернуть не так и пр. Уж лучше пусть код будет длиннее, но понятнее
Из этого поста я не понял, чем вы недовольны? :)
Я прекрасно знаю чем каст от as отличается. Но спасибо, что напомнили.
И я действительно не вижу что в моем коде потенциально опасного. Предложите, пожалуйста свой вариант.
Если вы сомневаетесь в смысле данных расширений, то это другое дело. Я не агитирую за их использование. Я просто предлагаю свой вариант. Мне он нужен, я его использую.

Мне он нужен, я его использую.

Покажите уже, как вы его используете.
ммм, да я вроде не вам отвечал, а nchaly, на его фразу
Потенциально опасные вызовы типа (X as Y).Z(). А что если X не приведется к Y?
Да, сорри, пропустил
А я бы переадресовал ваш вопрос автору статьи) Мне кажется, что вы задаете мне мой же вопрос - "зачем создавать себе изначально "потенциально опасные вызовы"".
мне просто показалось что вы ярый сторонник прямых кастов (просто подряд читал комменты и замечание ваше и GubkaBob - об одном. Очевидно что коду не хватает аккуратности в обработке различных узких мест, но это не значит что прямое приведение всегда предпочтительнее "as".
Может просто я приукрасил и сильно обобщил ваш взгляд, и пришел к неверным выводам. Хотел сказать только что прямое приведение не всегда лучше\выгоднее as.
ни о чем, очередной утилитный класс
объедените все свои утилитные классы в одну либу, выложите её на сорсфордж, напишите документацию с примерами, а тут киньте ссылку.
Промолчать никак? Одно могу посоветовать, если не нравится - не читайте мои посты, потому что я и дальше буду продолжать в том же духе. Практика показывает, что какое-никакое внимание они притягивают. А в связи с тем, что на сайте и вовсе нет материалов по .net я считаю, что ваш совет не обоснован.
Очень полезно перед Get/SetValue проверить, что значения не Read/WriteOnly.
Спасибо за полезный комментарий. Это действительно важно, позднее постараюсь обновить.
Sign up to leave a comment.

Articles