23

少し学術的な質問ですが、フレームワークの設計をより深いレベルで理解しようとしています。

だから私たちは持っていますString.IsNullOrEmpty(MyString)

enable の拡張メソッドを書くこともできmyString.IsNullOrEmpty()ますが、それは間違いなく最高のアイデアではありません。参照: IsNullOrEmpty を使用して String クラスを拡張すると混乱しますか? .

私の質問は、MS がこの機能を .Net フレームワークの一部として記述しないのはなぜですか? パフォーマンスに関する考慮事項はありますか?さらに一般的に言えば、String オブジェクトを介してアクセスできるように構築するのに十分な価値があると見なされるメソッドまたはプロパティが、文字列型のオブジェクトのメンバーとして使用できないのはなぜでしょうか?

4

3 に答える 3

35

静的メソッドString.IsNullOrEmptyは、.NET Framework バージョン 2.0 で導入されました。拡張メソッドは、LINQ と共に .NET Framework バージョン 3.5 で導入されました。したがって、Microsoft には、導入時にこのオプションがありませんでしたIsNullOrEmpty

もちろん、IsNullOrEmptyを のインスタンス メソッドにすることはできません。Stringこれは、 である参照に対してメソッドを呼び出すことができないためですnull。ただし、このような参照で拡張メソッドを呼び出すことはできます。これは、拡張メソッドの構文が静的メソッド呼び出しの構文糖衣にすぎないためです。


IsNullOrEmptyそれが拡張メソッドだったとしましょう。次に、次のように呼び出すことができます。

string s = null;
bool result = s.IsNullOrEmpty();

コメントでは、誰かがこの呼び出しがNullReferenceException. 拡張メソッドは次のように宣言されます。

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string s)
    {
        return s == null || s.Length == 0;
    }
}

...そして、このように使用されます...

 string s = null;
 bool result = s.IsNullOrEmpty();

...これは...の構文糖衣です

 string s = null;
 bool result = StringExtensions.IsNullOrEmpty(s);

...したがって、例外はスローされません。そうするのが良い考えかどうかは別の問題です (以下の usr から提供された回答を参照ください)。

于 2013-01-07T13:15:10.187 に答える
27

一般に、参照で呼び出されたときに拡張メソッドが失敗しないようにすることは、悪い習慣と見なされnullます。これは、コードを読んだだけでは、拡張メソッドが呼び出されていると判断できないためです。あなたの直感は、呼び出し((string)null).IsNullOrEmpty()が失敗することを確認することです。

明らかに、この種のメソッドはインスタンス メソッドとして使用できません。したがって、ここで直感に違反しています。

そうは言っても、私はすべての重要なプロジェクトでこの拡張機能を正確に定義しており、多くの場合、非常に便利です。私は、この小さなレベルの不純物と非直感性を喜んで受け入れます。

フレームワークの作成者は明らかに同意しませんでした。また、このメソッドは .NET Framework に入るべきではないと思います。これは一種の「高度な」ものであり、学習の妨げになるからです。初心者は、「えっ? null 参照で安全にメソッドを呼び出せる場合とできない場合がある? いつどうやって見分けるの?」と尋ねるかもしれません。

于 2013-01-07T13:10:24.393 に答える
6

null 文字列で使用できる場合IsNullOrEmpty()は、おそらくメソッドの名前をIsEmpty().

冗談はさておき、これがメソッドの実装方法です。

public static bool IsNullOrEmpty(string value)
{
  if (value != null)
    return value.Length == 0;
  else
    return true;
}

文字列インスタンスの場合、条件が常に真であることは明らかです。

また、細かいところを一つ。たとえば、string.Concatこれは静的メソッドです。たとえば、なぜ相対インスタンス メソッドがないのか不思議に思うのは当然のことかもしれません。その実装を見ると、彼らはこれらのメソッドを可能な限りフェイルプルーフにしたかったと思います. 引数をメソッドに渡すとき、null 参照の場合、例外がスローされる代わりに空の文字列に置き換えられます。これは、文字列に実際に値が含まれるか、null になるかが事前にわからない場合に役立ちます。フレームワークの開発者は、null 文字列を処理することでコードの読みやすさに貢献する方がよいと判断したと思います。空のものとして、エンドユーザーに追加のチェックを保存します。きっと、もしstring.Concatがインスタンス メソッドであった (または少なくとも代替手段があった) 場合、ユーザーは引き続き null 引数を渡すことができますが、操作対象のインスタンスは必ずしも null ではありません。

于 2013-01-07T13:06:57.803 に答える