Зачем this != null
От: _FRED_ Черногория
Дата: 26.05.08 11:53
Оценка: 57 (2)
Смотрю исходники System.String ("\redbits\ndp\clr\src\BCL\System\String.cs")
// Determines whether two strings match. 
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public override bool Equals(Object obj) { 
        String str = obj as String; 
        if (str == null)
        { 
                // exception will be thrown later for null this
                if (this != null) return false;
        }

        return EqualsHelper(this, str);
}

(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re: Зачем this != null
От: xvost Германия http://www.jetbrains.com/company/people/Pasynkov_Eugene.html
Дата: 26.05.08 11:56
Оценка: 10 (2)
Здравствуйте, _FRED_, Вы писали:

_FR>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


Мое мнение — копипэйст со статического Equals, где эта проверка осмыслена (ибо Equals(null, null) == true)
С уважением, Евгений
JetBrains, Inc. "Develop with pleasure!"
Re[2]: Зачем this != null
От: _FRED_ Черногория
Дата: 26.05.08 12:04
Оценка:
Здравствуйте, xvost, Вы писали:

_FR>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


X>Мое мнение — копипэйст со статического Equals, где эта проверка осмыслена (ибо Equals(null, null) == true)


Да как-то совсем не похоже на
// Determines whether two Strings match.
public static bool Equals(String a, String b) {
        if ((Object)a==(Object)b) {
                return true;
        }

        if ((Object)a==null || (Object)b==null) {
                return false;
        }

        return EqualsHelper(a, b);
}


В общем, если действительно глупость, то всё ясно и не интересно.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Зачем this != null
От: TK Лес кывт.рф
Дата: 26.05.08 12:17
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" :???: Индусы? "Наследие" C++? :maniac:


учитывая ситуацию, когда строки пытаются максимально подражать value типам такая проверка может выглядеть достаточно осмысленно. кроме того, всегда есть возможность вызвать string.Equals передав null в качестве this
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 26.05.08 12:18
Оценка: 36 (5)
Здравствуйте, _FRED_, Вы писали:

_FR>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


using System;

class A
{
    public virtual void Foo()
    {
        Console.WriteLine(this == null);
    }

    static void Main()
    {
        ((Action) Delegate.CreateDelegate(typeof(Action), null, ((Action) new A().Foo).Method))();
    }
}
Re[4]: Зачем this != null
От: _FRED_ Черногория
Дата: 26.05.08 12:33
Оценка:
Здравствуйте, TK, Вы писали:

_FR>>>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


TK>учитывая ситуацию, когда строки пытаются максимально подражать value типам такая проверка может выглядеть достаточно осмысленно.


То есть проверка value-типа на null выглядит осмысленно?

TK>кроме того, всегда есть возможность вызвать string.Equals передав null в качестве this


В смысле статический String.Equals(string, string)? Или на IL вызвать экземплярный Equals(string), передав в this пустой указатель? Пускай даже так
Автор: nikov
Дата: 26.05.08
возможно, вопрос: зачем это проверять? Почему, например, в классе Version рядом, который так же неизменяемый, подобных проверок нет?
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Зачем this != null
От: _FRED_ Черногория
Дата: 26.05.08 12:33
Оценка:
Здравствуйте, nikov, Вы писали:

_FR>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


N>        ((Action) Delegate.CreateDelegate(typeof(Action), null, ((Action) new A().Foo).Method))();


Круть virtual даже не нужным оказалось.
... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re: Зачем this != null
От: orangy Россия
Дата: 26.05.08 16:38
Оценка: 18 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>Смотрю исходники System.String ("\redbits\ndp\clr\src\BCL\System\String.cs")

_FR>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?

Инструкция callvirt используется для вызова всех (в том числе и невиртуальных) методов для многих языков, но не для всех. Именно она гарантирует this != null. В каком-нибудь языке компилятор мог бы определить, что данный тип суть sealed и Equals всегда будет использоваться известный, и в результате генерировать call, который не проверяется в момент вызова. Возможно, для строчек существует такая оптимизация в FCL, CLR или в каком-то другом месте, известном Microsoft.

Может, однако, быть и такое, что C#-компилятор когда-то на заре своей юности генерировал callvirt не во всех случаях, а в строчках просто завалялась проверочка

В любом случае, я сомневаюсь, что рассмотренный Nikov вариант является чем-то, для чего MS будет вставлять специальную проверку
... << RSDN@Home 1.2.0 alpha rev. 655>>
"Develop with pleasure!"
Re[2]: Зачем this != null
От: desco США http://v2matveev.blogspot.com
Дата: 27.05.08 06:55
Оценка: 6 (1)
Здравствуйте, nikov, Вы писали:

N>Здравствуйте, _FRED_, Вы писали:


_FR>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


N>
N>using System;

N>class A
N>{
N>    public virtual void Foo()
N>    {
N>        Console.WriteLine(this == null);
N>    }

N>    static void Main()
N>    {
N>        ((Action) Delegate.CreateDelegate(typeof(Action), null, ((Action) new A().Foo).Method))();
N>    }
N>}

N>


еще вариант
using namespace System;

int main(array<System::String ^> ^args)
{
    String^ s = nullptr;
    s->String::Equals("");
}


method assembly static int32 main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] string s)
    L_0000: ldnull 
    L_0001: stloc.0 
    L_0002: ldloc.0 
    L_0003: ldstr ""
    L_0008: call instance bool [mscorlib]System.String::Equals(string)
    L_000d: pop 
    L_000e: ldc.i4.0 
    L_000f: ret 
}
Re: Зачем this != null
От: Andrei F.  
Дата: 27.05.08 07:44
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


using namespace System;

ref class Test
{
public:
    void Foo()
    {
        if (this == nullptr)
            Console::WriteLine(L"Hello, Lucky World");
    }
};

int main(array<System::String ^> ^args)
{
    Test^ test = nullptr;
    test->Foo();
    return 0;
}
Re[2]: Зачем this != null
От: _FRED_ Черногория
Дата: 27.05.08 10:12
Оценка:
Здравствуйте, orangy, Вы писали:

_FR>>Смотрю исходники System.String ("\redbits\ndp\clr\src\BCL\System\String.cs")

_FR>>(то же и с перегруженной версией с параметром типа string) и не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?

O>Инструкция callvirt используется для вызова всех (в том числе и невиртуальных) методов для многих языков, но не для всех. Именно она гарантирует this != null.


OK

O>В каком-нибудь языке компилятор мог бы определить, что данный тип суть sealed и Equals всегда будет использоваться известный, и в результате генерировать call, который не проверяется в момент вызова.


OK, но правильно ли я понимаю, что выполнение условия "this == null" в таком случае будет означать ошибку в компиляторе, так как далее по коду есть обращения к this? Или нормальный, работающий компилятор мог бы "в некоторых случаях" законно вызвать метод, обращающийся к полям объекта так, что ссылка на this внутри метода будет пустая?

O>Может, однако, быть и такое, что C#-компилятор когда-то на заре своей юности генерировал callvirt не во всех случаях, а в строчках просто завалялась проверочка


Так это проверка, получается, от кривого компилятора? Я просто не понимаю, для чего эта провера в нормальном режиме работы? Примеры nikov-а и desco хоть и законны, но не должны обязывать защищаться от них.

O>В любом случае, я сомневаюсь, что рассмотренный Nikov вариант является чем-то, для чего MS будет вставлять специальную проверку


... << RSDN@Home 1 alpha 3 rev. 0>>
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.05.08 14:30
Оценка:
Здравствуйте, orangy, Вы писали:

O>В любом случае, я сомневаюсь, что рассмотренный Nikov вариант является чем-то, для чего MS будет вставлять специальную проверку


Ну это всего лишь иллюстрация того, что там может быть null, на удобном мне языке. То же самое, но без рефлекшна, можно сделать на ILASM или C++/CLI. Видимо, приведенный в начале код писался в расчете на взаимодействие с другими языками.
Re[3]: Зачем this != null
От: AngeL B. Россия  
Дата: 27.05.08 18:15
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ну это всего лишь иллюстрация того, что там может быть null, на удобном мне языке. То же самое, но без рефлекшна, можно сделать на ILASM или C++/CLI. Видимо, приведенный в начале код писался в расчете на взаимодействие с другими языками.


Хм, ... если исходить из такой логики, то тогда надо в начале каждого метода ставить такую проверку, т.к. используя особенности языков можно добиться ситуации this == null. Иначе библиотека "не расчитана на другие языки". Так что ли?
По мне так это _очень_ странная логика. Т.к. нигде, насколько я знаю, не оговоренно, что this может быть null в .NET языках.
Re[4]: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 27.05.08 19:12
Оценка: 16 (2)
Здравствуйте, AngeL B., Вы писали:

AB>Т.к. нигде, насколько я знаю, не оговоренно, что this может быть null в .NET языках.


Оговорено. Ecma-335, Partition I, 8.4.2 Methods:

An instance method is invoked by specifying a class and the instance method within that class. The
object passed as this can be null (a special value indicating that no instance is being specified) or an instance of
any type that inherits (see §8.9.8) from the class that defines the method.

Re[5]: Зачем this != null
От: AngeL B. Россия  
Дата: 27.05.08 20:36
Оценка: 2 (1) +1
Здравствуйте, nikov, Вы писали:

N>

N>An instance method is invoked by specifying a class and the instance method within that class. The
N>object passed as this can be null (a special value indicating that no instance is being specified) or an instance of
N>any type that inherits (see §8.9.8) from the class that defines the method.


1) Спасибо!
2) Ой-ой-ой как все запущено. Тогда у меня возникает другой не менее интересный вопрос. А зачем такая возможность была оговорена в стандарте? Какой смысл в instance-методе при this == null? Только для того чтобы иметь возможность не делать такую проверку перед вызовом и иметь при этом осмысленно выполняемый код?
Ведь стандарт просто так с потолка не пишут. И если там это есть, то должны были быть достаточно сильные аргументы.
Re[6]: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 28.05.08 15:52
Оценка:
Здравствуйте, AngeL B., Вы писали:

AB>А зачем такая возможность была оговорена в стандарте? Какой смысл в instance-методе при this == null?

AB>Ведь стандарт просто так с потолка не пишут. И если там это есть, то должны были быть достаточно сильные аргументы.

Насчет мотивации затрудняюсь ответить.
Re: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 20.06.08 08:42
Оценка: 2 (1)
Здравствуйте, _FRED_, Вы писали:

_FR>не понимаю, зачем проверка "this != null" Индусы? "Наследие" C++?


Кстати, в C# 3.0 есть способ загнать null в this без использования рефлекшна, но по-моему это баг:

using System;
using System.Linq.Expressions;

class A
{
    static void Main()
    {
        Expression<Action<A>> e = x => new Action(x.Foo)();
        e.Compile()(null);
    }

    void Foo()
    {
        Console.WriteLine(this == null);
    }
}
Re[2]: Зачем this != null
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.06.08 09:09
Оценка:
Здравствуйте, nikov, Вы писали:

N>Кстати, в C# 3.0 есть способ загнать null в this без использования рефлекшна


Как это без использования? Expression внутри содержит всякие MethodInfo, да и DynamicMethod это тоже рефлекшен.
... <<RSDN@Home 1.2.0 alpha 4 rev. 1090 on Windows Vista 6.0.6001.65536>>
AVK Blog
Re[3]: Зачем this != null
От: nikov США http://www.linkedin.com/in/nikov
Дата: 20.06.08 09:31
Оценка:
Здравствуйте, AndrewVK, Вы писали:

N>>Кстати, в C# 3.0 есть способ загнать null в this без использования рефлекшна


AVK>Как это без использования? Expression внутри содержит всякие MethodInfo, да и DynamicMethod это тоже рефлекшен.


Да, согласен. Хотел написать "без явного использования".
Как бы оно там внутри не было реализовано, оно не должно нарушать правила языка. Кстати, вот несколько интересных багов с expression trees, которые проявляются в SP1 Beta, и которые так и не успевают исправить в SP1.

1)
// Debug configuration only!
using System;
using System.Linq.Expressions;

class A
{
    public static bool operator true(A x)
    {
        return true;
    }

    public static bool operator false(A x)
    {
        return false;
    }
}

class B : A
{
    public static B operator |(B x, B y)
    {
        return new B();
    }

    static bool op_True<T>(B x)
    {
        return true;
    }

    static bool op_False(B x)
    {
        return false;
    }

    static void Main()
    {
        Expression<Func<B, A>> ex = x => x || x;
        ex.Compile()(null);
    }
}


2)
using System;
using System.Linq.Expressions;

struct A
{
    static void Main()
    {
        Func<A?, D> f = y => (D)y;
        f(null);

        Expression<Func<A?, D>> x = y => (D)y;
        x.Compile()(null);
    }
}

class B
{
    public static implicit operator B(A x)
    {
        return new D();
    }
}

class D : B { }


3)
using System;
using System.Linq.Expressions;

abstract class A
{
    static void Main()
    {
        Expression<Func<A, Action>> ex = x => x.Foo;
        var a = ex.Compile()(null);
        a();
    }

    public abstract void Foo();
}
Re[4]: Зачем this != null
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.06.08 09:36
Оценка:
Здравствуйте, nikov, Вы писали:

N>Как бы оно там внутри не было реализовано, оно не должно нарушать правила языка.


Рантайма, ты хотел сказать? При помощи динамической компиляции можно нарушать любые правила языка, если они не противоречат рантайму.

N> Кстати, вот несколько интересных багов с expression trees, которые проявляются в SP1 Beta, и которые так и не успевают исправить в SP1.


В SP1 меняют компилятор???
... <<RSDN@Home 1.2.0 alpha 4 rev. 1090 on Windows Vista 6.0.6001.65536>>
AVK Blog
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.