6

重複の可能性:
なぜこれをチェックするのですか!= null?

// Determines whether two strings match. 
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
public override bool Equals(Object obj)
{
    //this is necessary to guard against reverse-pinvokes and
    //other callers who do not use the callvirt instruction
    if (this == null)
        throw new NullReferenceException();

    String str = obj as String;
    if (str == null) 
        return false;

    if (Object.ReferenceEquals(this, obj)) 
        return true;

    return EqualsHelper(this, str);
}

私が理解していない部分は、現在のインスタンスthisをnullに対してチェックしているという事実です。コメントは少し紛らわしいので、そのコメントは実際にはどういう意味なのか疑問に思いました。

そのチェックがなかった場合にこれがどのように壊れるかの例を誰かが挙げることができますか?これは、そのチェックをクラスに配置する必要があることを意味しますか?

4

2 に答える 2

6

thisこのチェックは、nullポインターを使用して関数を呼び出す可能性のあるネイティブ コードに対するガードとして存在します。これは C# では発生しないため、コードに同様のガードを配置する必要はありません。C# が完成する前にクラスが作成された可能String性は十分にあり、作成者は null を防ぐことが重要であると考えていた可能性がありStringます。または、null でメソッドを簡単に呼び出すことができるネイティブ コードやその他の場所からメソッドを呼び出すことが一般的である可能性があります。

nullthisで呼び出されてガードがなくても、例外がわずかに異なるだけであることに注意してください。別の例外である可能性があり、別のメンバーによってスローされる可能性がありますが、それ以外の場合は違いが生じる可能性はほとんどありません。

言い換えると、null チェックが存在しない場合、EqualsHelper(またはその呼び出し先の 1 つ) は ではなく例外をスローしますEquals。ユーザーに表示される関数の内部を非表示にすることが望ましいため、最初にチェックを入れるのが理にかなっています。

于 2012-04-16T05:33:26.853 に答える
2
  • Languages like C# and VB.NET use callvirt to throw NullReference before an instance method is entered (this == null) checks are not necessary.
  • Languages like F# and Managed C++ (most of the time) use the call instruction where you can get into an instance method with a null this pointer. (this == null) does have an effect.

The added null check is not only meant for the latter languages but also to aid debuggability to throw at the location where the error (call an instance method of a null object) does occur. If it were not there you can call any method inside the class without any error as long as this is never dereferences (accesses member variables). This can go so far that on your null object several method calls did work and suddenly you get a null reference exception back (the method where instance data was accessed).

If you look at the checks inside the .NET classes it is clear that only on some prominent classes like string do contain such guards. Other methods like IndexOf do not guard against this. This is inconsistent but I do think the performance penalty for such double null checks were not worth the effort because most users of the BCL are languages which uses the callvirt instruction where a second null check does not help.

于 2012-04-16T06:33:40.937 に答える