Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Получения данных CallStack, Доступ к CallStack c параметрами 
:(
    Опции темы
Lomir
Дата 11.6.2009, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 30.1.2007
Где: Lithuania::Kaunas

Репутация: нет
Всего: 1



Возможно ли в С# получить данные с котороми на стеке была вызвана функция?
т.е. в идеале хочу сделать что то вроде:
Код

void SomeFunction(object someObj1, object someObj2)
{
    ValidateNotNull();

}

void ValidateNotNull() 
{
    StackTrace trace = new StackTrace();
    foreach(var param = trace.GetFrame(1).GetMethod().GetParameters())
    {
        // так ты знаем только тип параметров, но не переданное значение
        // а возможно ли получить еще и значение someObj1, someObj2? Чтобы сделать что то похожее:
        if (значение == null)
            throw new Exception("{0} is null" param.Name);
    }
}

Или может можно решить проблему в проверкой на null входящих параметров как нибуть проще?
PM MAIL ICQ Skype   Вверх
PashaPash
Дата 11.6.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Lomir, очень простое решение - просто вручную проверять параметры на null. В разы читабельнее, и работает в случае "все должны быть не null, кроме одного".


--------------------
PM MAIL WWW   Вверх
Lomir
Дата 12.6.2009, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 30.1.2007
Где: Lithuania::Kaunas

Репутация: нет
Всего: 1



Цитата

Lomir, очень простое решение - просто вручную проверять параметры на null. В разы читабельнее, и работает в случае "все должны быть не null, кроме одного". 

ИМХО Это не решение. Весь достаточно тупой код должен ренерироваться автоматически во время исполнения с помощью шаблонов, рефлексии и т.д. Зачем в ручную проверять в КАЖДОЙ функции парамерты и плодить сотни ненужных строк тупого кода, если это можно автоматизировать (если конечно можно вытащить значение парамертов из стэка). Лично мне очень не нравиться когда открываешь функцию с 4 или больше парамертами и видеш екран, а то и полтора екрана, тупых проверок типо:
Код

if (param != null)
{
  throw new SomeException("param is null");
}

Гораздо читабельнее иметь один метор Validate(); который проверят состояние обьекта на пригодность работы + проверяет нужные входящие парамерты на not null. А потом сразу сама логика функции.




PM MAIL ICQ Skype   Вверх
PashaPash
Дата 12.6.2009, 09:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Цитата(Lomir @  12.6.2009,  09:02 Найти цитируемый пост)
ИМХО Это не решение. Весь достаточно тупой код должен ренерироваться автоматически во время исполнения с помощью шаблонов, рефлексии и т.д. Зачем в ручную проверять в КАЖДОЙ функции парамерты и плодить сотни ненужных строк тупого кода, если это можно автоматизировать (если конечно можно вытащить значение парамертов из стэка).

Затем что только сама функция (ее автор) знают как именно валидировать параметры. И набор правил в общем случае уникален для КАЖДОЙ функции. "Не рабтать если someObj1 == null" - это часть самой логики функции, а не общее ограничение вообще  всех функций в приложении.  "все параметры не null" - достаточно редкий случай, и, IMHO, не стоит потенциальных проблем с производительностью.

Если часто видишь по полтора экрана проверок - то у тебя в коде функции часто принимают по 10-15 параметров, и надо что-то в консерватории менять, а не вставлять uber-хаки.

По теме - сомневаюсь в самой возможности вытащить значения из стэка без отладчика - между { и вызовом Validate происходит довольно много действий (в debug) и значений someObj1, someObj2 с стэке может уже не быть.


--------------------
PM MAIL WWW   Вверх
Lomir
Дата 12.6.2009, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 30.1.2007
Где: Lithuania::Kaunas

Репутация: нет
Всего: 1



По 10-15 уж точно не передаються, а вот по 4-6 довольно часто. 6 обьеков это 24 строчки безсмысленного кода. В случае когда какие то парамерты могут быть null утчен, работает немного измененный выриант.
Код

void SomeFunction(object someObj1, object someObj2)
{
    ValidateNotNull(someObj1, someObj2);
}
void ValidateNotNull(param object[] parameters) 
{
    foreach(var param in parameters)
    {
       if (param == null)
       {
          // List upperParam = GetListOfProvidedParametersInUpperFuntion();
          // Map parameter via ref equality and get its name
          // Or maybe there is other way to get parameter param name?
          throw new Exception("{0} is null", paramName);
       }
    }
}

Если какой-то параметр может быть null, мы его просто не передаем в ValidateNotNull и он не проверяется. При этом этот вариант не будет иметь никаких проблем с производительность, так как тут используется рефлексия тока в случаенеправильного использования, и оно будет исправленно.

Это не uber-хак, а просто обощение стандартный действий програмиста. По такой логике можно сказать что generic'и и мета-програмирование это тоже  uber-хаки.

ИМХО проверка параметров не является частью логики функции, так как не является полезной работой функции (а в конечной версии програмы этот код вопше не используется). В особо критических ко времени приложениях обычно вопше ничего не проверяют, а просто пишут в документации и в случае неправильных параметров получают Undefined Behavior.

Как обьекты могут быть не на стеке? Они же могут (и даже будут) использоваться после успешного окончания функции ValidateNotNull().
PM MAIL ICQ Skype   Вверх
archeg
Дата 12.6.2009, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 612
Регистрация: 6.1.2007
Где: Киев

Репутация: 11
Всего: 27



Вообще для этого существуют всякие либы типа Spring.net или Enterprise Library. И не надо придумывать велосипеды)


--------------------
ИМХО задница есть универсальный интерфейс. Ибо через задницу можно сделать абсолютно ВСЕ (bash.org.ru)

Дядька всегда можно спросить в аське, если не задалбывать - не откажет smile
И вообще, на самом деле я студент, и ненавижу обращение на "Вы") Тут все свои  ;)
PM MAIL ICQ Jabber   Вверх
PashaPash
Дата 12.6.2009, 21:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1233
Регистрация: 3.1.2008

Репутация: 13
Всего: 49



Цитата(Lomir @  12.6.2009,  09:55 Найти цитируемый пост)
По 10-15 уж точно не передаються, а вот по 4-6 довольно часто. 6 обьеков это 24 строчки безсмысленного кода. В случае когда какие то парамерты могут быть null утчен, работает немного измененный выриант.

Цитата(Lomir @  12.6.2009,  09:55 Найти цитируемый пост)

Если какой-то параметр может быть null, мы его просто не передаем в ValidateNotNull и он не проверяется. При этом этот вариант не будет иметь никаких проблем с производительность, так как тут используется рефлексия тока в случаенеправильного использования, и оно будет исправленно.

Этот вариант лучше, но тоже хромает - т.к. упирается в ту же проблему - достать значения из чужого стэка, что проблематично без отладочных символов.
Может быть что-то этого, в качестве компромиса
Код

        void ValidateNotNull(Dictionary<string, object> parameters) 
        {
            foreach(var param in parameters)
            {
               if (param.Value == null)
               {
                   throw new ArgumentNullException(param.Key);
               }
            }
        }

        void SomeFunction(object someObj1, object someObj2)
        {
            ValidateNotNull(new Dictionary<string, object>()
            {
                { "someObj1", someObj1 },
                { "someObj2", someObj2 }
            });
        }


Цитата(Lomir @  12.6.2009,  09:55 Найти цитируемый пост)
Это не uber-хак, а просто обощение стандартный действий програмиста. По такой логике можно сказать что generic'и и мета-програмирование это тоже  uber-хаки.

generic'и не пытаются вывести тип из имени переменной. хотя было бы неплохо - var intStringDictionary = new(); вот когда научатся - тоже станут убер-хаками.
Цитата(Lomir @  12.6.2009,  09:55 Найти цитируемый пост)
ИМХО проверка параметров не является частью логики функции, так как не является полезной работой функции (а в конечной версии програмы этот код вопше не используется). В особо критических ко времени приложениях обычно вопше ничего не проверяют, а просто пишут в документации и в случае неправильных параметров получают Undefined Behavior.

Для критических ко времени приложений существуют Trace/Debug.Assert, которые можно вырезать из релиза.

Цитата(Lomir @  12.6.2009,  09:55 Найти цитируемый пост)
Как обьекты могут быть не на стеке? Они же могут (и даже будут) использоваться после успешного окончания функции ValidateNotNull(). 

Зато значения (теоретически) могут быть не те. Например, проц/jit могут переставить местами строки 4 и 5. Причем вылезет это только в release configuration.
Код

void SomeFunction(object someObj1, object someObj2)
{
    var someNewValue = new object();
    ValidateNotNull();
    someObj1 = someNewValue;
}


Добавлено через 12 минут и 1 секунду
archeg, да, интерсепторы вполне решают проблему, довольно красиво. Но велосипеды - интереснее ;)


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0781 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.