9

だから、私は拡張メソッドを使うのが本当に楽しいです..多分少し多すぎます。それで、私は私が行き過ぎないことを確実にするために私の最新の楽しみについて尋ねるつもりです。

シナリオは、Guid?渡される変数があることです。変数がnullまたはGuid.Emptyである場合は、別のGUIDを使用します。そこで、英語のように読めるように拡張メソッドを作成しました。

    internal static Guid OrIfEmpty(this Guid? guid, Guid other)
    {
        if (!guid.HasValue || guid.Value == Guid.Empty)
        {
            return other;
        }
        return guid.Value;
    }

これは、「nullthis」が例外をスローしないことを自動的に意味します。たとえば、これは機能します。

((Guid?)null).OrIfEmpty(other);

これは拡張メソッドを使用しないと不可能であり、私の意見ではかなり誤解を招く可能性があります。しかし、それはとても簡潔できれいです!それで、あなたはどう思いますか?これは許容できることですか、それとも他のプログラマーにとって混乱しすぎる可能性がありますか?

また、私がこのようなことをしthisてnullをチェックする他のシナリオもあると確信していますが、これは私が今持っている最良の例です。

注:私はGuid?特にこのビジネスについてはあまり質問していません。実装されている全体的なパターンについてもっと質問しています(可能な場合は拡張メソッドがありthisますnull

4

5 に答える 5

5

これは、拡張メソッドを使用しないと不可能です

確かに、makeは通常の静的メソッド呼び出しです(これはすべての拡張メソッドです):

私の意見では、かなり誤解を招く可能性があります

インスタンスでインスタンスメソッドを呼び出しているように見えるので、同意しnullます。それはもっと悪いかもしれません:

string s = null;
string n = s.OrIfEmpty("empty");

一見すると、これは明らかNullReferenceExceptionに待っているように見えますが、コンパイルされ、設計どおりに機能します。

あなたの質問は本当に意見を求めるだけなので、正しい答えは1つではありませんが、私は確かに慎重で、thisパラメータがである可能性があることを示すために拡張メソッドを文書化しますnull。または(@quezalcoatlが示すように)null値をサポートすることをより明確にするために名前を変更します。

internal static Guid OrIfNullOrEmpty(this Guid? guid, Guid other)
于 2013-01-28T16:06:52.547 に答える
3

私は個人的に、より良く、より速く理解する開発者がはるかに増えると思います(したがって、最終的にはコードがよりクリーンになることを意味します):

if (!guid.HasValue || guid.Value == Guid.Empty)
{
    return other;
}

それよりも:

((Guid?)null).OrIfEmpty(other);

したがって、自分でコーディングしているのか、自分が書いたものを他の人がサポートできるのかによって異なります。個人的には、付加価値は「奇妙さ」の価値があるとは思いません:)

于 2013-01-28T16:02:03.220 に答える
1

一般に、拡張メソッドはnull値をチェックする必要があります。結局のところ、拡張メソッドは、コンパイラーがインスタンスメソッドのように扱うことができるように、構文糖衣が追加された静的メソッドにすぎません。

たとえば、これがある場合:

public static class MyExtensions
{
    public static IEnumerable<TSource> Frob<TSource>(this TSource source)
    {
        // do stuff here
    }
}

次に、2つの異なる方法で呼び出すことができます。

var foo = new List<int>();
var bar = foo.Frob();  // called like an instance method
var barby = MyExtensions.Frob(foo); // called like a static method

通常のインスタンスメソッドでthisはnullではないと想定できますが、拡張メソッドではその想定を行うことはできません。

于 2013-01-28T16:04:54.040 に答える
1

何の問題もありません。思い出してください

string.IsNullOrEmptyOrWhitespace

それはstdlibから来ています。

一般に、それはそのnullの場合に何をするかによって異なります。関数を通常の方法で使用し、関数がその特殊なケースで正常に動作する場合は、すべて問題ありません。しかし、関数がデバッグモードになり、システムの再構成を開始した場合は、驚き最小の原則を超えており、それは良くありません。

--注:@JeppeStigNielsenが正確に指摘しているように、INOEOWは現在のバージョンの.Netの拡張メソッドではありません。拡張メソッドとして数回使用したことは確かですが、おそらくCTPバージョンにあったか、まったく存在しなかった古いバージョンの.Netのカスタムアドオンでした。混乱させて申し訳ありません!それにもかかわらず、「それはすべて適切な命名についてです」というスタイルが成り立ちます!:)

于 2013-01-28T16:06:02.367 に答える
0

これで大丈夫だと思います。Nullable<Guid>の例はそれほど悪くないことに注意してください。いわゆるnullタイプは、 「何もない」ではなくNullable<Guid>、の実際の既存の値であるためです。Nullable<Guid>

そのため、次のように、この種の「null」でインスタンスメソッドを使用することもできます。

Guid? g = null;
g.GetValueOrDefault();  // OK; real instance method

これを参照型で使用すると、さらに「奇妙」になります。

internal static string OrIfEmpty(this string str, string other)
{
  return string.IsNullOrEmpty(str) ? other : str;
}

それなら、「本当の」ヌルでそれを呼び出すことができるからです。

string s = null;
s.OrIfEmpty("unspecified");  // OK; s is a true null reference
于 2013-01-28T16:08:48.697 に答える