私は属性が非常に役立つことを知っています。[Browsable(false)]
プロパティタブでプロパティを非表示にできるなど、事前定義されたものがあります。属性を説明するよい質問があります:.NETの属性とは何ですか?
プロジェクトで実際に使用する定義済みの属性(およびその名前空間)は何ですか?
私は属性が非常に役立つことを知っています。[Browsable(false)]
プロパティタブでプロパティを非表示にできるなど、事前定義されたものがあります。属性を説明するよい質問があります:.NETの属性とは何ですか?
プロジェクトで実際に使用する定義済みの属性(およびその名前空間)は何ですか?
回答:
[DebuggerDisplay]
デバッグ中にTypeのインスタンスの上にマウスを置くと、Typeのカスタマイズされた出力をすばやく確認するのに非常に役立ちます。例:
[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
public string FirstName;
public string LastName;
}
これはデバッガでどのように見えるかです:
また、プロパティが設定された[WebMethod]
属性CacheDuration
により、Webサービスメソッドの不要な実行を回避できることにも言及する価値があります。
System.Obsolete
私の意見では、フレームワークで最も有用な属性の1つです。使用されなくなったコードに関する警告を発する機能は非常に便利です。私は、開発者に何かをもう使用しないように伝える方法と、理由を説明して何かを行うためのより良い/新しい方法を指摘する方法が大好きです。
Conditional attribute
デバッグの使用のためにあまりにもかなり便利です。これにより、リリース用のソリューションをビルドするときにコンパイルされないデバッグ目的のコードにメソッドを追加できます。
次に、Webコントロールに固有の属性がたくさんありますが、それらはより具体的であり、サーバーコントロールの開発以外には何の用途もありません。
[Flags]
かなり便利です。確かに構文上の砂糖ですが、それでもかなりいいです。
[Flags]
enum SandwichStuff
{
Cheese = 1,
Pickles = 2,
Chips = 4,
Ham = 8,
Eggs = 16,
PeanutButter = 32,
Jam = 64
};
public Sandwich MakeSandwich(SandwichStuff stuff)
{
Console.WriteLine(stuff.ToString());
// ...
}
// ...
MakeSandwich(SandwichStuff.Cheese
| SandwichStuff.Ham
| SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"
レッピーは私が気づかなかったことを指摘し、それがこの属性に対する私の熱意を弱めています:それはコンパイラーに列挙変数の有効な値としてビットの組み合わせを許可するように指示しません、コンパイラーは関係なくこれを列挙のために許可します。C ++の背景が透けて見える ... ため息
[Flags]
単なる構文上の糖よりも大きな用途があります。Webサービスを使用しているときに、次のような値SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jam
が渡された場合、シリアル化/非シリアル化は機能しません。この[Flags]
属性がないと、デシリアライザーは値がフラグの組み合わせである可能性があることを認識しません。私のWCFが機能しなかった理由を考えて約2日間費やした後、これを一生懸命学びました。
[DebuggerStepThrough]
System.Diagnosticsが好きです。
これらの1行の何もしないメソッドやプロパティへのステップインを回避するのに非常に便利です(自動プロパティのない初期の.Netで作業する必要がある場合)。短いメソッド、またはプロパティのゲッターまたはセッターに属性を配置すると、デバッガーで「ステップイン」を押しても、すぐに飛ぶことができます。
その価値については、すべての.NET属性のリストを次に示します。数百あります。
他の人については知りませんが、真剣なRTFMが必要です。
私の投票は Conditional
[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
// your code here
}
これを使用して、高度なデバッグ機能を備えた関数を追加できます。のようにDebug.Write
、デバッグビルドでのみ呼び出されるため、プログラムのメインフローの外部で複雑なデバッグロジックをカプセル化できます。
ユーザーコントロール、カスタムコントロール、またはプロパティグリッドを介して編集するクラスのパブリックプロパティではDisplayName
、常にDescription
とDefaultValue
属性を使用します。これらのタグは、名前、説明パネル、およびデフォルト値に設定されていない太字の値をフォーマットするために.NET PropertyGridによって使用されます。
[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
...
}
Description
XMLコメントが見つからない場合、Visual StudioのIntelliSenseが属性を考慮に入れたいと思います。同じ文を2回繰り返す必要がなくなります。
Description
列挙型で使用した場合..あなたまで私のためにその最も役立つの
[Serializable]
xmlなどの外部データソースとの間またはリモートサーバーからオブジェクトをシリアル化および逆シリアル化するために常に使用されます。詳細はこちら。
ホフスタットの精神では、[Attribute]
属性は非常に便利です。これは、独自の属性を作成する方法だからです。プラグインシステムの実装、Enumsへの説明の追加、複数のディスパッチやその他のトリックのシミュレーションには、インターフェイスではなく属性を使用しました。
これは、興味深い属性InternalsVisibleToに関する投稿です。基本的には、C ++フレンドアクセス機能を模倣しています。単体テストには非常に便利です。
internal
公開されていないあなたの主張に同意しません。これは、テストされているアセンブリ内でパブリックであり、アセンブリ内の他のクラスが修正機能を想定できるように、ユニットテストする必要があります。単体テストを行わない場合は、使用するすべてのクラスでその機能をテストする必要があります。
私は[DefaultValue]
非常に便利であることがわかりました。
私は、nUnitライブラリから提案[TestFixture]
します。[Test]
コードの単体テストは、リファクタリングと体系化されたドキュメントの安全性を提供します。
これはフレームワークで適切な名前が付けられておらず、十分にサポートされていないため、パラメーターを必要とするべきではありませんが、この属性は不変クラスの有用なマーカーです。
[ImmutableObject(true)]
ImmutableObjectAttribute
クラスを作成する方が良いでしょう-少なくともパラメータを削除することができます。
[ThreadStatic]
属性をスレッドおよびスタックベースのプログラミングと組み合わせて使用するのが好きです。たとえば、残りの呼び出しシーケンスと共有したい値が必要であるが、帯域外(つまり、呼び出しパラメーターの外側)にしたい場合は、次のようなものを使用できます。
class MyContextInformation : IDisposable {
[ThreadStatic] private static MyContextInformation current;
public static MyContextInformation Current {
get { return current; }
}
private MyContextInformation previous;
public MyContextInformation(Object myData) {
this.myData = myData;
previous = current;
current = this;
}
public void Dispose() {
current = previous;
}
}
私のコードの後半では、これを使用して、私のコードの下流の人々に帯域外のコンテキスト情報を提供できます。例:
using(new MyContextInformation(someInfoInContext)) {
...
}
ThreadStatic属性を使用すると、問題のスレッドのみに呼び出しのスコープを設定して、スレッド間のデータアクセスの厄介な問題を回避できます。
MyContextInformation.Current
で、スタック上のアクティブなコンテキストを取得するためにアクセスできます。これは特定のケースで非常に優れた概念であり、私たち(私の会社)のエンジンは多くの目的で使用しています。
DebuggerHiddenAttributeデバッグするべきではないコードにステップを回避することができます。
public static class CustomDebug
{
[DebuggerHidden]
public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}
...
// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception());
また、スタックトレースにメソッドが表示されないようにします。これは、別のメソッドをラップするだけのメソッドがある場合に便利です。
[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
return GetElementAt(position.X, position.Y);
}
public Element GetElementAt(Single x, Single y) { ... }
ここで呼び出しGetElementAt(new Vector2(10, 10))
て、ラップされたメソッドでエラーが発生した場合、呼び出しスタックには、エラーをスローするメソッドを呼び出しているメソッドが表示されません。
DesignerSerializationVisibilityAttribute
とても便利です。ランタイムプロパティをコントロールまたはコンポーネントに配置し、デザイナーにそれをシリアル化させたくない場合は、次のように使用します。
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
get { return baz; }
set { baz = value; }
}
[Browsable(false)]
場所で、デザイナーのユーザーからそれを隠す[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
ために必要です。
少数の属性だけがコンパイラーサポートを取得しますが、属性の非常に興味深い用途の1つはAOPです。PostSharpは、カスタム属性を使用してメソッドにILを注入し、あらゆる種類の機能を許可します...ログ/トレースは簡単な例ですが、他のいくつかの良い例自動INotifyPropertyChanged実装(ここ)のようなものです。
発生してコンパイラまたはランタイムに直接影響を与えるもの:
[Conditional("FOO")]
-このメソッドの呼び出し(引数の評価を含む)は、ビルド中に「FOO」シンボルが定義されている場合にのみ発生します[MethodImpl(...)]
-同期、インライン化などのいくつかのことを示すために使用されます[PrincipalPermission(...)]
-セキュリティチェックをコードに自動的に挿入するために使用[TypeForwardedTo(...)]
- 呼び出し元を再構築せずにアセンブリ間でタイプを移動するために使用されますリフレクションを介して手動でチェックされるものについて-私はSystem.ComponentModel
属性の大ファンです。、、のようなもの[TypeDescriptionProvider(...)]
で[TypeConverter(...)]
、[Editor(...)]
データバインディングシナリオでの型の動作を完全に変更できます(動的プロパティなど)。
私は使用しています [DataObjectMethod]
最近ます。ObjectDataSource(または他のコントロール)でクラスを使用できるように、メソッドについて説明します。
[DataObjectMethod(DataObjectMethodType.Select)]
[DataObjectMethod(DataObjectMethodType.Delete)]
[DataObjectMethod(DataObjectMethodType.Update)]
[DataObjectMethod(DataObjectMethodType.Insert)]
[TypeConverter(typeof(ExpandableObjectConverter))]
(コントロールの)クラスであるプロパティを展開するようにデザイナーに指示します
[Obfuscation]
アセンブリ、タイプ、またはメンバーに対して指定されたアクションを実行するように難読化ツールに指示します。(通常、アセンブリレベルを使用しますが[assembly:ObfuscateAssemblyAttribute(true)]
私が好きな中間層の開発者であること
System.ComponentModel.EditorBrowsableAttribute
プロパティを非表示にして、UI開発者が表示する必要のないプロパティに圧倒されないようにすることができます。
System.ComponentModel.BindableAttribute
データバインドする必要がないものもあります。繰り返しになりますが、UI開発者が行う必要のある作業が軽減されます。
私DefaultValue
はローレンス・ジョンストンが言ったのも好きです。
System.ComponentModel.BrowsableAttribute
そしてその Flags
定期的に使用されます。
私が使う
System.STAThreadAttribute
System.ThreadStaticAttribute
必要なときます。
ところで。これらはすべての.Netフレームワーク開発者にとって同様に価値があります。
[EditorBrowsable(EditorBrowsableState.Never)]
プロジェクトがソリューションにない場合、IntelliSenseからプロパティとメソッドを非表示にすることができます。Fluentインターフェイスの無効なフローを非表示にするのに非常に役立ちます。どのくらいの頻度でGetHashCode()またはEquals()を実行しますか?
MVCの[ActionName("Name")]
場合、GetアクションとPostアクションを同じメソッドシグネチャで持つか、アクション名にダッシュを使用することができます。そうしないと、ルートを作成しないと不可能になります。
以下の属性も非常に重要であることをここで言及することは重要だと思います。
STAThreadAttribute
アプリケーションのCOMスレッドモデルがシングルスレッドアパートメント(STA)であることを示します。
たとえば、この属性はWindowsフォームアプリケーションで使用されます。
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
そしてまた...
SuppressMessageAttribute
特定の静的分析ツールルール違反の報告を抑制し、単一のコードアーティファクトに対して複数の抑制を許可します。
例えば:
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
string fileIdentifier = name;
string fileName = name;
string version = String.Empty;
}
CodeSmithを介してデータエンティティクラスを生成し、いくつかの検証ルーチンに属性を使用します。次に例を示します。
/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
get { return _firmGUID; }
set { _firmGUID = value; }
}
そして、データエンティティクラスに関連付けられた属性に基づいて検証を行うユーティリティクラスを取得しました。これがコードです:
namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
/// <summary>
/// Data entity validation
/// </summary>
/// <param name="data">Data entity object</param>
/// <returns>return true if the object is valid, otherwise return false</returns>
public static bool Validate(object data)
{
bool result = true;
PropertyInfo[] properties = data.GetType().GetProperties();
foreach (PropertyInfo p in properties)
{
//Length validatioin
Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
if (attribute != null)
{
ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
if (validLengthAttribute != null)
{
int maxLength = validLengthAttribute.MaxLength;
int minLength = validLengthAttribute.MinLength;
string stringValue = p.GetValue(data, null).ToString();
if (stringValue.Length < minLength || stringValue.Length > maxLength)
{
return false;
}
}
}
//Range validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
if (attribute != null)
{
ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
if (validRangeAttribute != null)
{
decimal maxValue = decimal.MaxValue;
decimal minValue = decimal.MinValue;
decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
decimal decimalValue = 0;
decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
if (decimalValue < minValue || decimalValue > maxValue)
{
return false;
}
}
}
//Regex validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
if (attribute != null)
{
ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
if (validRegExAttribute != null)
{
string objectStringValue = p.GetValue(data, null).ToString();
string regExString = validRegExAttribute.RegExString;
Regex regEx = new Regex(regExString);
if (regEx.Match(objectStringValue) == null)
{
return false;
}
}
}
//Required field validation
attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
if (attribute != null)
{
ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
if (validRequiredAttribute != null)
{
object requiredPropertyValue = p.GetValue(data, null);
if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
{
return false;
}
}
}
}
return result;
}
}
}
[DeploymentItem("myFile1.txt")]
DeploymentItemに関するMSDNドキュメント
これは、ファイルに対してテストする場合、またはファイルをテストへの入力として使用する場合に非常に役立ちます。
[System.Security.Permissions.PermissionSetAttribute]
宣言型セキュリティを使用して、PermissionSetのセキュリティアクションをコードに適用できます。
// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
// The immediate caller is required to have been granted the FullTrust permission.
[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
public FullConditionUITypeEditor() { }
}