4


1

.NET 2.0のC#拡張メソッド
NET2.0で拡張メソッドを機能させる方法へのリンクがいくつか見つかりました(http://www.danielmoth.com/Blog/2007/05/using-extension-methods-in-fx-20.html[The moth ]、http://kohari.org/2008/04/04/extension-methods-in-net-20/ [Discord&Rhyme]、https://stackoverflow.com/questions/1522605/using-extension-methods- in-net-2-0 [スタックオーバーフロー])。 私は同僚から漠然と聞いたことがありますが、これは図書館か何かで問題を引き起こすのですか? これは事実ですか? また、3つすべてが異なる方法を使用します。

The moth

namespace System.Runtime.CompilerServices
{
  public class ExtensionAttribute : Attribute { }
}
namespace System.Runtime.CompilerServices
{
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public class ExtensionAttribute : Attribute {}
}
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class
         | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute {}
}

これらの方法の違いは何ですか、どの方法をお勧めしますか?

5 Answer


4


最終的には、大きな違いはありません。ランタイムに一致するものが優先されると主張することができますが、_ideal_の答えは.NET 3.5に切り替えることです(そうしないと、後日スコープ内の同じ属性の異なるバージョンと混同される可能性があります)。

`[AttributeUsage]`は、何もしないものにアタッチされるのを防ぎます-しかし、とにかく_by self_のようなことはしません…​

タイプに対するメタデータを見ると、正確な属性の使用法はstackoverflowのバリアントに最も似ているように見えますが、最終的にこれはそれほど重要ではありません-_name_と_namespace_は重要です(そしてそれは `Attribute`から継承します)。


1


違いは十分単純です:

最初の例では、属性をどこにでも配置できます。 2番目の例では、メソッドにのみ適用できます。同じメソッドに複数を適用することはできず、メソッドがオーバーライドされた継承クラスは属性を継承しません。 3番目の例では、メソッド、クラス、またはアセンブリに適用できます。

他の場所で適用しようとすると、コンパイラエラーが発生します。

2番目は最も理にかなっているようです。


1


_DiscordとRhyme_をお勧めします。これは、属性の適用方法に意味のある制約を提供するためです。

  1. メソッドにのみ適用できます

  2. 一度だけ適用できます

  3. 属性を継承できません


1


個人的には、3つすべてを避けることをお勧めします。 各オプションは、「トリック」を実行することでこの機能を実現します-実稼働コードではこれに依存しません。

拡張メソッドを使用する場合は、C#3.0にアップグレードします。 それ以外の場合は、非拡張メソッド構文を使用してメソッドを呼び出すだけにしてください。

次のような拡張メソッド呼び出しをいつでも実行できます。

public static class Utility {
    public static string Extension(this string original) { ... }

// call with:
var newString = myString.Extension();

そして、それを直接呼び出します:

string newString = Utility.Extension(myString);

これは、C#/。NET 2構文との整合性が向上するため、推奨されます。


1


SOバージョンは正確なバージョンです。正確を期すために使用する必要があります。

Fwiw、AttributeTarget.Method指定子は非常に明確です。 クラスとアセンブリはそれほど重要ではありません。 C#とVB.NETコンパイラの両方が、拡張メソッドを含む静的クラス/モジュールの属性を発行します。 そして、クラス/モジュールを含むアセンブリ上。 なぜこれを行うのかはあまり明確ではないので、適切にコンパイルする必要はありません。 これは作業中の最適化であり、コンパイラとIntelliSenseの両方が拡張メソッドをいつ考慮すべきかを発見するのに役立つと思います。

アセンブリに適用される属性を取得することは、実際には問題です。 コードを.netmodulesにコンパイルするとき、それは正しく機能しません。 しかし、それは非常にあいまいな問題です。