Вызов null.SomeMethod();
От: _ichensky Европа https://github.com/ichensky
Дата: 08.10.15 15:14
Оценка: 5 (1) -8 :))
Здравствуйте,
Глупая бага .net . Почему ее не исправят?

...
        public static void SomeMethod<T>(this ICollection<T> items) 
        {
            if (items == null)
                items = new List<T>();
        }
...
class User {
    ...
    public virtual ICollection<Group> Groups { get; set; }
}
...
void func(){
    ...
    user.Groups.SomeMethod();
    // here: user.Groups == null
}


До и после вызова user.Groups.SomeMethod()
user.Groups == null

но по идее интерпретатор .net должен пердать в метод SomeMethod сслыку на поле user.Groups,
или выкинуть исключение потому что мы пишем код так
null.SomeMethod();
а то зачем нам в С# строгая типизация

а он в тихую отрабатывает метод.
Підтримати Україну у боротьбі з країною-терористом.

https://prytulafoundation.org/
https://u24.gov.ua/

Слава Збройним Силам України!!! Героям слава!!!
Re: Вызов null.SomeMethod();
От: keenn  
Дата: 08.10.15 15:55
Оценка: 5 (1) +7
_>Глупая бага .net . Почему ее не исправят?

Я бы начал с того, что отказался от термина "интерпретатор .net", т.к. вы путаете интерпретатор с компилятором.

Далее, вам нужно смириться с мыслью, что extension methods — это всего лишь статические методы (пусть и несколько особого типа, позволяющие в симбиозе с компилятором и intellisens-ос создать определенные удобства для программиста).

Смирившись с этой мыслью, вы поймете, что никакого "бага" здесь нет, и никакой "интерпретатор" не должен "выкидывать исключения".
Re[2]: Вызов null.SomeMethod();
От: _ichensky Европа https://github.com/ichensky
Дата: 08.10.15 18:20
Оценка:
Здравствуйте, keenn, Вы писали:

K>Я бы начал с того, что отказался от термина "интерпретатор .net", т.к. вы путаете интерпретатор с компилятором.

тогда уж среда исполнения, а то .нет компилит методы в рантайме по мере необходимости

K>Далее, вам нужно смириться с мыслью, что extension methods — это всего лишь статические методы

метод не обязательно должен быть статическим
все зависит от того какой базовый тип у передаваемого параметра в одном случае это IInterface<T> а в другой случае если напр укажем тип object, а потом в теле метода скастим items as IInterface<T> то все будет норм.
Підтримати Україну у боротьбі з країною-терористом.

https://prytulafoundation.org/
https://u24.gov.ua/

Слава Збройним Силам України!!! Героям слава!!!
Re[3]: Вызов null.SomeMethod();
От: keenn  
Дата: 08.10.15 18:38
Оценка: +1
_>тогда уж среда исполнения, а то .нет компилит методы в рантайме по мере необходимости

Вы опять путаете, теперь уже jit и компилятор

_>метод не обязательно должен быть статическим

_>все зависит от того какой базовый тип у передаваемого параметра в одном случае это IInterface<T> а в другой случае если напр укажем тип object, а потом в теле метода скастим items as IInterface<T> то все будет норм.

Extension method именно статический. Не очень понял вашу мысль, продемонстрируйте кодом плз.
Re: Вызов null.SomeMethod();
От: Caracrist https://1pwd.org/
Дата: 08.10.15 19:08
Оценка:
Здравствуйте, _ichensky, Вы писали:


_>

_>        public static void SomeMethod<T>(this ICollection<T> items) 
_>        {
_>                items = new List<T>(); // что вы хотели этим добиться? :xz:
_>        }
_>
~~~~~
~lol~~
~~~ Single Password Solution
Re: Вызов null.SomeMethod();
От: _NN_ www.nemerleweb.com
Дата: 08.10.15 19:27
Оценка: +4
Здравствуйте, _ichensky, Вы писали:

_>Здравствуйте,

_>Глупая бага .net . Почему ее не исправят?

А в чём баг ?

static void F(string x) {}
static void G(this string x) {}

F(null); // Можно ведь ? Можно.
G(null); // Можно ведь ? Можно.
a.G() // на самом деле тоже что и G(a) , значит тоже можно.


Лучшим решением будет проверять на null и кидать ArgumentNullException.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Вызов null.SomeMethod();
От: Философ Ад http://vk.com/id10256428
Дата: 08.10.15 20:10
Оценка: +1 -1
Здравствуйте, _ichensky, Вы писали:

_>Здравствуйте,

_>Глупая бага .net . Почему ее не исправят?

_>
_>...
_>        public static void SomeMethod<T>(this ICollection<T> items) 
_>        {
_>            if (items == null)
_>                items = new List<T>();
_>        }
_>


Действительно глупая бага, но .net а ваша. Правильно будет вот так:

        public static void SomeMethod<T>(this ICollection<T> items) 
        {
            if (items == null)
               throw new System.ArgumentNullExcetion("items");
        }


Исключение ArgumentNullExcetion специально предназначено для таких случаев. Читайте "Microsoft patterns & practices" там есть рекомендации для таких случаев.
Всё сказанное выше — личное мнение, если не указано обратное.
Re[2]: Вызов null.SomeMethod();
От: _ichensky Европа https://github.com/ichensky
Дата: 09.10.15 07:52
Оценка:
Здравствуйте, Caracrist, Вы писали:


_>> items = new List<T>(); // что вы хотели этим добиться?


        public static void RemoveAndAttach<T>(this ICollection<T> toItems, IEnumerable<T> items)
        {
            if (toItems == null)
                toItems = new List<T>();
            else
                toItems.Clear();

            foreach (var item in items)
                toItems.Add(item);
        }

Все было ради такого метода, entity framework helper a,
если бы все получилось можно было бы писать код так

user.Groups.RemoveAndAttach(groups);
user.Roles.RemoveAndAttach(roles);
groups.Roles.RemoveAndAttach(roles);

и не делать проверку на null перед каждыми вызовом этого метода,
а если объект был создан то не вызывать для него метод Clear.
Підтримати Україну у боротьбі з країною-терористом.

https://prytulafoundation.org/
https://u24.gov.ua/

Слава Збройним Силам України!!! Героям слава!!!
Re[3]: Вызов null.SomeMethod();
От: _NN_ www.nemerleweb.com
Дата: 09.10.15 10:02
Оценка:
Здравствуйте, _ichensky, Вы писали:

_>Все было ради такого метода, entity framework helper a,

_>если бы все получилось можно было бы писать код так

Переходим на VS2015 и C# 6.
Меняем "." на "?.".
И магия работает на нас.

_>
_>user.Groups?.RemoveAndAttach(groups);
_>user.Roles?.RemoveAndAttach(roles);
_>groups.Roles?.RemoveAndAttach(roles);
_>

_>и не делать проверку на null перед каждыми вызовом этого метода,
_>а если объект был создан то не вызывать для него метод Clear.

Получаем автоматическую проверку на null где указали "?.".

Подробности: Null-conditional Operators
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Вызов null.SomeMethod();
От: alexzz  
Дата: 09.10.15 20:52
Оценка: +2 :)
Здравствуйте, _ichensky, Вы писали:

_>>> items = new List<T>(); // что вы хотели этим добиться?


_>
_>        public static void RemoveAndAttach<T>(this ICollection<T> toItems, IEnumerable<T> items)
_>        {
_>            if (toItems == null)
_>                toItems = new List<T>();
_>            else
_>                toItems.Clear();

_>            foreach (var item in items)
_>                toItems.Add(item);
_>        }
_>


После выхода из метода нигде не останется ссылок на только что созданный список, и он будет уничтожен первым же вызовом сборщика мусора, так и не успев толком пожить.
Re[4]: Вызов null.SomeMethod();
От: fmiracle  
Дата: 09.10.15 21:19
Оценка: +1
Здравствуйте, _NN_, Вы писали:

_NN>Получаем автоматическую проверку на null где указали "?.".


Это соответствует тому, что написал ТС в коде, но не тому, чего он хотел получить (а хотел он поведения ref-параметра для extension метода)
Re[5]: Вызов null.SomeMethod();
От: _NN_ www.nemerleweb.com
Дата: 10.10.15 06:35
Оценка: -1 :)
Здравствуйте, fmiracle, Вы писали:

F>Это соответствует тому, что написал ТС в коде, но не тому, чего он хотел получить (а хотел он поведения ref-параметра для extension метода)


Ну тогда это просто неправильный язык выбран.

C++/CLI наше всё:


using namespace System;
using namespace System::Collections::Generic;

void F(List<int>^% l)
{
    if (l == nullptr)
    {
        l = gcnew List<int>();
    }

    l->Add(1);
}

int main(array<System::String ^> ^args)
{
    List<int>^ l;
    F(l);

    Console::WriteLine("Count = {0}", l->Count);
    Console::WriteLine("l[0] = {0}", l[0]);

    return 0;
}


Count = 1
l[0] = 10

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Вызов null.SomeMethod();
От: _ichensky Европа https://github.com/ichensky
Дата: 10.10.15 10:54
Оценка:
Здравствуйте, fmiracle, Вы писали

F>Это соответствует тому, что написал ТС в коде, но не тому, чего он хотел получить (а хотел он поведения ref-параметра для extension метода)

Если метод и класс будут не статическими, то такой код снова не будет работать
Підтримати Україну у боротьбі з країною-терористом.

https://prytulafoundation.org/
https://u24.gov.ua/

Слава Збройним Силам України!!! Героям слава!!!
Re[3]: Вызов null.SomeMethod();
От: Vladek Россия Github
Дата: 10.10.15 17:49
Оценка: 18 (1)
Здравствуйте, _ichensky, Вы писали:

_>
_>user.Groups.RemoveAndAttach(groups);
_>user.Roles.RemoveAndAttach(roles);
_>groups.Roles.RemoveAndAttach(roles);
_>

_>и не делать проверку на null перед каждыми вызовом этого метода,
_>а если объект был создан то не вызывать для него метод Clear.

Это вы нам принцип Tell, don't ask описываете. Хороший принцип, которому вы начали следовать, но остановились на полпути. Проверка на null, вызов метода Clear — это не конечная цель вашего кода, вы хотите заменить у пользователя роли. Так заставьте объект пользователя самого заменять свои роли и не спрашивайте у него как он это сделает!

user.AssignRoles(roles);


Дальше, надеюсь, понятно как реализовать метод AssignRoles и ему подобные? Если нет, по ссылке всё разобрано на примере. И вот, кстати, отличная цитата:

Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.

Отредактировано 10.10.2015 17:52 Vladek . Предыдущая версия . Еще …
Отредактировано 10.10.2015 17:50 Vladek . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.