Atribut Paling Berguna [ditutup]

784

Saya tahu bahwa atribut sangat berguna. Ada beberapa yang sudah ditentukan sebelumnya [Browsable(false)]yang memungkinkan Anda untuk menyembunyikan properti di tab properti. Berikut adalah pertanyaan yang menjelaskan atribut: Apa itu atribut di .NET?

Apa atribut yang telah ditentukan (dan namespace mereka) yang Anda gunakan dalam proyek Anda?

bijaksana
sumber
27
Pertanyaan apa? , seluruh halaman dipenuhi dengan jawaban yang indah dengan penjelasan yang luar biasa. Sementara saya membaca ini, saya mendapat pengalaman seperti mewawancarai banyak ahli tentang pandangan mereka. +100 untuk pertanyaannya.
Muthu Ganapathy Nathan
Saya setuju, pertanyaan-pertanyaan seperti ini adalah beberapa yang paling berharga - membuat SO kurang bermanfaat sehingga ditutup.
David Thielen

Jawaban:

669

[DebuggerDisplay]dapat sangat membantu untuk dengan cepat melihat output kustom dari Tipe ketika Anda mengarahkan mouse pada instance Type selama debugging. contoh:

[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
    public string FirstName;
    public string LastName;
}

Beginilah seharusnya terlihat di debugger:

teks alternatif

Juga, perlu disebutkan bahwa [WebMethod]atribut dengan CacheDurationset properti dapat menghindari eksekusi yang tidak perlu dari metode layanan web.

Vivek
sumber
62
Wow, itu benar-benar baik untuk diketahui. Saya biasanya menyelesaikan hal yang sama dengan mengganti ToString, tetapi ini lebih baik.
Brian
17
Hati-hati dengan ini, itu menggigit jauh lebih besar dari CPU Anda daripada ToString.
Nikola Radosavljević
1
Anda juga dapat menggunakan ini untuk menampilkan hasil metode. Ini bisa membuat pengalaman debugging yang cukup membingungkan jika metode (atau properti-dapatkan) memiliki efek samping.
Øyvind Skaar
4
@ NikolaRadosavljević akan hanya mengambil daya CPU selama debugging
Nickolay Kondratyev
2
@Nickolay Kondratyev: Saya tidak tahu semua seluk beluk, tetapi Anda dapat melihat dalam mengikuti praktik terbaik layanan web yang dapat membawa Anda ke beberapa kesimpulan: blogs.msdn.com/b/jaredpar/archive/2011/03/ 18 /…
Nikola Radosavljević
273

System.Obsoleteadalah salah satu atribut paling berguna dalam kerangka kerja, menurut saya. Kemampuan untuk meningkatkan peringatan tentang kode yang seharusnya tidak lagi digunakan sangat berguna. Saya suka memiliki cara untuk memberi tahu pengembang bahwa sesuatu tidak boleh lagi digunakan, serta memiliki cara untuk menjelaskan mengapa dan menunjukkan cara yang lebih baik / baru dalam melakukan sesuatu.

Ini Conditional attributejuga cukup berguna untuk penggunaan debug. Ini memungkinkan Anda untuk menambahkan metode dalam kode Anda untuk tujuan debug yang tidak akan dikompilasi ketika Anda membangun solusi Anda untuk rilis.

Lalu ada banyak atribut khusus untuk Kontrol Web yang menurut saya berguna, tetapi lebih spesifik dan tidak memiliki kegunaan di luar pengembangan kontrol server dari apa yang saya temukan.

Dan Herbert
sumber
50
Anda dapat melewatkan "true" sebagai salah satu parameter ke System.Obsolete yang menyebabkan peringatan menjadi kesalahan karena itu merusak build. Jelas ini harus dilakukan setelah Anda membersihkan semua peringatan. :)
Adrian Clark
14
Setelah Anda membersihkan semua peringatan, bukankah lebih baik menghapus metode itu saja?
Pedro
10
@Pedro: Terkadang Anda tidak bisa karena alasan kompatibilitas. Jika bersifat pribadi dan tidak digunakan, ya, hapus saja.
Fantius
3
@plinth Melempar pengecualian akan menjadi ide yang buruk karena berbagai alasan, # 1 adalah alasan utama untuk menggunakan Obsolete () adalah agar Anda dapat tetap membuat kode yang dikompilasi bekerja saat dalam fase transisi. Jika Anda tidak mengizinkan siapa pun memanggil metode ini, mengapa tidak menghapus saja?
Dan Herbert
17
@plinth Ini untuk mencegah kode baru menggunakan metode ini. Kode lama akan tetap kompatibel biner jika metode ditandai usang, tetapi akan berhenti berfungsi jika Anda melempar pengecualian. Jika seseorang menggunakan refleksi untuk berkeliling "Obsolte" bendera, maka Anda memiliki masalah lebih buruk ...
Dan Herbert
204

[Flags]cukup berguna. Gula sintaksis sudah pasti, tetapi masih agak bagus.

[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"

Leppie menunjukkan sesuatu yang tidak saya sadari, dan yang agak mengurangi antusiasme saya untuk atribut ini: ia tidak memerintahkan kompiler untuk mengizinkan kombinasi bit sebagai nilai valid untuk variabel enumerasi, kompiler memungkinkan ini untuk enumerasi terlepas. Latar belakang C ++ saya menunjukkan melalui ... menghela napas

Shog9
sumber
Jadi apa sebenarnya yang dilakukan atribut Flags?
Andrei Rînea
13
Saya harap kalian menyadari atribut Flags tidak mengganggu semua. Tidak diperlukan / digunakan sama sekali, kecuali untuk TypeConverter.
leppie
3
@ leppie: ToString () juga. Tapi ... wow. Untuk beberapa alasan, saya telah mengharapkan perilaku enumerasi tanpa atribut sama dengan C ++: atau nilai-nilai menghasilkan bilangan bulat (tidak dapat diteruskan apa adanya dengan metode mengharapkan enum param). Saya melihat sekarang bukan itu masalahnya. Lemah ... ok, .NET enum payah.
Shog9
2
[Bendera] benar-benar hanya membantu fungsi debugger dan .ToString () tahu bahwa nilai berpotensi kombinasi dari beberapa deklarasi di enum. Saya tidak yakin, itu mungkin membuat Intellisense membantu Anda menggunakan enum lebih efektif juga.
Kenzi
31
[Flags]memang memiliki penggunaan yang lebih besar daripada sekadar gula sintaksis. Saat menggunakan layanan web, serialisasi / de-serialisasi tidak akan berfungsi jika nilai suka SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamdilewatkan. Tanpa [Flags]atribut deserializer tidak akan tahu bahwa nilainya dapat berupa kombinasi flag. Belajar ini dengan cara yang sulit setelah menghabiskan sekitar dua hari untuk memikirkan mengapa WCF saya tidak berfungsi.
Anchit
177

Saya suka [DebuggerStepThrough]dari System.Diagnostics .

Ini sangat berguna untuk menghindari melangkah ke metode atau properti do-nothing satu baris (jika Anda dipaksa untuk bekerja di .Net awal tanpa properti otomatis). Letakkan atribut pada metode pendek atau pengambil atau penyetel properti, dan Anda akan terbang tepat saat menekan "step into" di debugger.

Blair Conrad
sumber
5
Berkali-kali saya berharap saya tahu tentang properti ini
cepat
1
Sayang sekali sudah rusak dengan penutupan - lihat gregbeech.com/blogs/tech/archive/2008/10/17/… untuk info lebih lanjut.
Greg Beech
3
Juga bermanfaat untuk setiap WM_Paint Code yang Anda tahu berfungsi :)
Pondidum
@GregBeech URL itu mengembalikan kesalahan .NET. Berkelas! :)
smdrager
@smdrager - Pasti masalah sementara, sepertinya bekerja untuk saya hari ini.
Greg Beech
135

Untuk apa nilainya, berikut adalah daftar semua atribut .NET . Ada beberapa ratus.

Saya tidak tahu tentang orang lain tetapi saya memiliki beberapa RTFM yang serius untuk dilakukan!

wprl
sumber
33
daftar yang diposting untuk .net 1.1 di sini adalah daftar untuk 3.5 msdn.microsoft.com/en-us/library/system.attribute.aspx (Anda harus sedikit gulir ke bawah)
kay.one
2
Memperbarui tautan dalam pertanyaan. Sekarang ini adalah daftar lengkap untuk 3,5
R. Martinho Fernandes
8
Sebenarnya itu tautan ke yang terbaru, bukan 3,5 khusus.
Brian Ortiz
1
Sekarang jika saja daftar itu bukan hanya daftar tautan, tetapi nama dan deskripsi. Baiklah. @BrianOrtiz benar. Daftarnya ada di versi 4.5.
Luminous
Anda cukup mengubah kerangka yang Anda targetkan di bagian atas di mana dikatakan "Versi Lain".
Novaterata
129

Pilihan saya adalah untuk Conditional

[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
    // your code here
}

Anda dapat menggunakan ini untuk menambahkan fungsi dengan fitur debugging canggih; seperti Debug.Write, ini hanya disebut dalam debug build, dan dengan demikian memungkinkan Anda untuk merangkum logika debug kompleks di luar aliran utama program Anda.

Steve Cooper
sumber
5
Bukankah ini sama dengan melakukan # jika DEBUG?
Neil N
10
Agaknya, #jika DEBUG berarti penelepon juga tidak boleh memanggilnya, sedangkan Conditioinal meninggalkan panggilan tetapi menjadikannya NOP yang dihilangkan di JIT.
Rangoric
23
Juga, Anda biasanya akan menggunakan # jika DEBUG di sekitar panggilan , dan [Bersyarat] di sekitar metode . Jadi jika Anda memanggil metode debugging 100 kali, mematikannya adalah masalah perubahan kode tunggal, bukan 100.
Steve Cooper
13
Komentar Rangoric agak salah (setidaknya untuk C #): metode ini termasuk yang tidak dimodifikasi; situs panggilan itu sendiri dihilangkan. Ini memiliki beberapa implikasi: parameter tidak dievaluasi, dan metode kondisional terkandung, tidak dimodifikasi, dalam output kompiler. Anda dapat memverifikasi ini dengan refleksi. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/…
Mark Sowul
97

Saya selalu menggunakan DisplayName, Descriptiondan DefaultValueatribut atas properti publik dari kontrol pengguna saya, kontrol khusus atau kelas apa pun yang saya akan edit melalui kisi properti. Tag ini digunakan oleh .NET PropertyGrid untuk memformat nama, panel deskripsi, dan nilai tebal yang tidak disetel ke nilai default.

[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
    ...
} 

Saya hanya berharap Visual Studio's IntelliSense akan mempertimbangkan Descriptionatribut jika tidak ada komentar XML ditemukan. Itu akan menghindari harus mengulangi kalimat yang sama dua kali.

Anthony Brien
sumber
3
Tidak percaya tidak ada yang menunjukkan Descriptionsampai Anda .. Ini yang paling membantu bagi saya ketika digunakan dengan enum ..
nawfal
68

[Serializable]digunakan sepanjang waktu untuk serialisasi dan deserializing objek ke dan dari sumber data eksternal seperti xml atau dari server jauh. Lebih lanjut di sini.

Gilligan
sumber
Ini sebenarnya disebut sebagai psuedoattribute, karena C # memancarkan bendera metadata untuk [Serializable], bukan turunan atribut khusus;)
TraumaPony
1
Sementara [Serializable] yang sangat berguna masih jauh dari sempurna. Itu membutuhkan terlalu banyak mengutak-atik dan coba-coba untuk mendapatkan hasil yang Anda inginkan.
shoosh
Saya akan kedua shoosh itu!
John Bubriski
System.NonSerializedAttribute berguna jika Anda ingin lebih mengontrol serialisasi otomatis.
CSharper
Sebagai catatan saya akan menambahkan bahwa kinerja serialisasi .Net cukup miskin, seperti 2 atau 3 pesanan lebih lambat dari kode kerajinan tangan.
redcalx
57

Dalam semangat Hofstadtian, [Attribute]atributnya sangat berguna, karena itulah cara Anda membuat atribut Anda sendiri. Saya telah menggunakan atribut alih-alih antarmuka untuk mengimplementasikan sistem plugin, menambahkan deskripsi ke Enums, mensimulasikan banyak pengiriman dan trik lainnya.

C. Lawrence Wenham
sumber
13
Terdengar keren! Maukah Anda menunjukkan beberapa contoh sistem plugin dan deskripsi enum? Itu adalah dua hal yang saya tertarik untuk mengimplementasikan sendiri!
John Bubriski
46

Berikut adalah postingan tentang atribut menarik InternalsVisibleTo . Pada dasarnya apa yang dilakukannya meniru fungsi akses teman-teman C ++. Ini sangat berguna untuk pengujian unit.

xrost
sumber
7
Bukankah maksud Anda berguna untuk meretas unit test pada sesuatu yang tidak bisa / tidak boleh diuji?
the_drow
@the_drow: Anda berbicara tentang 'aksesor pribadi': msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx
habakuk
@habakuk: Tidak juga. Ada beberapa kasus di mana kelas internal harus diekspos untuk pengujian unit, biasanya karena desain yang buruk.
the_drow
2
@the_drow: Saya tidak akan mengatakan bahwa InternalsVisibleTo adalah jahat untuk pengujian unit; Anda dapat membuat dan menguji "unit" yang lebih kecil yang tidak terlihat di luar proyek Anda (ini membantu Anda memiliki api kecil dan bersih). Tetapi jika Anda membutuhkan 'aksesor pribadi' untuk menguji sesuatu, mungkin ada sesuatu yang salah.
habakuk
10
@the_drow Saya tidak setuju dengan pernyataan Anda yang internaltidak publik. Ini publik dalam majelis yang sedang diuji dan harus diuji unit sehingga kelas-kelas lain dalam majelis dapat menganggap fungsi koreksi itu. Jika Anda tidak mengujinya, Anda harus menguji fungsinya di semua kelas konsumsi.
tvanfosson
28

Saya akan menyarankan [TestFixture]dan [Test]- dari perpustakaan nUnit .

Tes unit dalam kode Anda memberikan keamanan dalam refactoring dan dokumentasi terkodifikasi.

Adrian Wible
sumber
26
[XmlIgnore]

karena ini memungkinkan Anda untuk mengabaikan (dalam serialisasi xml apa saja) objek 'induk' yang jika tidak akan menyebabkan pengecualian saat menyimpan.

jimi
sumber
25

Itu tidak bernama, tidak didukung dalam kerangka kerja, dan seharusnya tidak memerlukan parameter, tetapi atribut ini adalah penanda yang berguna untuk kelas yang tidak dapat diubah:

[ImmutableObject(true)]
Neil Whitaker
sumber
6
Menurut dokumen, hanya digunakan pada waktu desain (sayangnya).
Hans Ke st ing
1
Mengingat ini hanya desain-waktu, mungkin akan lebih baik untuk membuat ImmutableObjectAttributekelas Anda sendiri - setidaknya Anda bisa menghilangkan parameter.
Roy Tinker
25

Saya suka menggunakan [ThreadStatic]atribut dalam kombinasi dengan pemrograman berbasis thread dan stack. Misalnya, jika saya ingin nilai yang ingin saya bagikan dengan sisa urutan panggilan, tetapi saya ingin melakukannya di luar jalur (yaitu di luar parameter panggilan), saya mungkin menggunakan sesuatu seperti ini.

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;
    }
}

Kemudian dalam kode saya, saya dapat menggunakan ini untuk memberikan informasi kontekstual dari band kepada orang-orang di hilir dari kode saya. Contoh:

using(new MyContextInformation(someInfoInContext)) {
   ...
}

Atribut ThreadStatic memungkinkan saya untuk membatasi panggilan hanya ke utas yang dimaksud menghindari masalah berantakan dari akses data di utas.

Ajaxx
sumber
dan bagaimana cara mengaksesnya? Jangan pahami titik sampel penggunaan Anda di sini. Bisakah Anda jelaskan?
Beachwalker
@Beachwalker Current harus statis, edit sekarang. Sekarang Anda dapat mengakses MyContextInformation.Currentuntuk mendapatkan konteks aktif di stack. Ini adalah sesuatu yang merupakan konsep yang sangat baik dalam kasus-kasus tertentu, mesin kami (perusahaan saya) menggunakannya untuk banyak tujuan.
Felix K.
23

The DebuggerHiddenAttribute yang memungkinkan untuk menghindari langkah ke dalam kode yang tidak harus debugged.

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()); 

Itu juga mencegah menampilkan metode dalam jejak stack, berguna ketika memiliki metode yang hanya membungkus metode lain:

[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
    return GetElementAt(position.X, position.Y);
}

public Element GetElementAt(Single x, Single y) { ... }

Jika sekarang Anda memanggil GetElementAt(new Vector2(10, 10))dan terjadi kesalahan pada metode terbungkus, tumpukan panggilan tidak menunjukkan metode yang memanggil metode yang melempar kesalahan.

Felix K.
sumber
21

DesignerSerializationVisibilityAttributesangat bermanfaat. Saat Anda meletakkan properti runtime pada kontrol atau komponen, dan Anda tidak ingin perancang untuk membuat serial, Anda menggunakannya seperti ini:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
konfigurator
sumber
4
sangat berguna untuk komponen WinForms. gunakan bersama dengan [Browsable (false)]
Mark Heath
3
Poin bagus - [Browsable(false)]diperlukan untuk menyembunyikannya dari pengguna perancang, di mana [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]diperlukan agar tidak diserialisasi.
konfigurator
17

Hanya beberapa atribut yang mendapatkan dukungan kompiler, tetapi satu penggunaan atribut yang sangat menarik adalah di AOP: PostSharp menggunakan atribut yang dipesan lebih dahulu untuk menyuntikkan IL ke dalam metode, memungkinkan segala macam kemampuan ... mencatat / melacak menjadi contoh sepele - tetapi beberapa contoh bagus lainnya adalah hal-hal seperti implementasi INotifyPropertyChanged otomatis (di sini ).

Beberapa yang terjadi dan berdampak langsung ke kompiler atau runtime :

  • [Conditional("FOO")] - panggilan ke metode ini (termasuk evaluasi argumen) hanya terjadi jika simbol "FOO" didefinisikan selama pembuatan
  • [MethodImpl(...)] - Digunakan untuk menunjukkan beberapa hal seperti sinkronisasi, inlining
  • [PrincipalPermission(...)] - Digunakan untuk menyuntikkan pemeriksaan keamanan ke dalam kode secara otomatis
  • [TypeForwardedTo(...)]- Digunakan untuk memindahkan tipe antar majelis tanpa membangun kembali penelepon

Untuk hal-hal yang diperiksa secara manual melalui refleksi - Saya penggemar System.ComponentModelatribut; hal-hal seperti [TypeDescriptionProvider(...)],, [TypeConverter(...)]dan [Editor(...)]yang sepenuhnya dapat mengubah perilaku tipe dalam skenario pengikatan data (yaitu properti dinamis, dll).

Marc Gravell
sumber
15

Jika saya akan melakukan merangkak cakupan kode, saya pikir keduanya akan menjadi teratas:

 [Serializable]
 [WebMethod]
FlySwat
sumber
15
[WebMethod] digunakan untuk menghias metode yang diekspos dalam layanan web. [Serializable] menandai objek Anda sedemikian rupa sehingga objek dapat diserialisasi untuk tujuan seperti memindahkannya melintasi domain aplikasi.
Kev
15

Saya telah menggunakan [DataObjectMethod]akhir - akhir ini. Ini menjelaskan metode sehingga Anda dapat menggunakan kelas Anda dengan ObjectDataSource (atau kontrol lainnya).

[DataObjectMethod(DataObjectMethodType.Select)] 
[DataObjectMethod(DataObjectMethodType.Delete)] 
[DataObjectMethod(DataObjectMethodType.Update)] 
[DataObjectMethod(DataObjectMethodType.Insert)] 

Info lebih lanjut

lebih bijaksana
sumber
12

Dalam proyek kami saat ini, kami menggunakan

[ComVisible(false)]

Ini mengontrol aksesibilitas tipe atau anggota yang dikelola perorangan, atau semua tipe dalam suatu majelis, ke COM.

Info lebih lanjut

Ahmed
sumber
12
[TypeConverter(typeof(ExpandableObjectConverter))]

Memberitahu desainer untuk memperluas properti yang merupakan kelas (dari kendali Anda)

[Obfuscation]

Menginstruksikan alat kebingungan untuk mengambil tindakan yang ditentukan untuk pertemuan, jenis, atau anggota. (Meskipun biasanya Anda menggunakan level Majelis[assembly:ObfuscateAssemblyAttribute(true)]

Chris S
sumber
1
Saya memang menebak, tetapi ternyata salah. Atribut Kebingungan hanya merupakan petunjuk untuk obfsucator pihak ke-3. Itu tidak menyebabkan kompiler mengaburkan apa pun secara default.
Dan Is Fiddling By Firelight
@Bisa Bebas untuk pengguna Visual Studio Pro / Ultimate!
Chris S
4
Jika Anda merujuk ke DotFuscator Community Edition, tingkat perlindungan yang disediakan sangat rendah sehingga yang terbaik hampir tidak ada artinya.
Dan Is Fiddling By Firelight
@ricovox Saya telah menambahkan ringkasan
Chris S
9

Atribut yang paling saya gunakan adalah yang terkait dengan Serialisasi XML.

XmlRoot

XmlElement

XmlAttribute

dll ...

Sangat berguna saat melakukan parsing atau serialisasi XML yang cepat dan kotor.

Brannon
sumber
8

Menjadi pengembang tingkat menengah yang saya sukai

System.ComponentModel.EditorBrowsableAttribute Mengizinkan saya menyembunyikan properti sehingga pengembang UI tidak kewalahan dengan properti yang tidak perlu mereka lihat.

System.ComponentModel.BindableAttributeBeberapa hal tidak perlu menjadi basis data. Sekali lagi, kurangi pekerjaan yang harus dilakukan pengembang UI.

Saya juga suka DefaultValueyang disebutkan oleh Lawrence Johnston.

System.ComponentModel.BrowsableAttribute dan Flags digunakan secara teratur.

saya menggunakan System.STAThreadAttribute System.ThreadStaticAttribute saat dibutuhkan.

Ngomong-ngomong. Saya ini sama berharganya untuk semua pengembang .Net framework.

ElGringoGrande
sumber
8

[EditorBrowsable(EditorBrowsableState.Never)]memungkinkan Anda untuk menyembunyikan properti dan metode dari IntelliSense jika proyek tidak ada dalam solusi Anda. Sangat membantu untuk menyembunyikan aliran yang tidak valid untuk antarmuka yang lancar. Seberapa sering Anda ingin GetHashCode () atau Equals ()?

Untuk MVC [ActionName("Name")]memungkinkan Anda untuk memiliki tindakan Dapatkan dan Posting tindakan dengan metode tanda tangan yang sama, atau menggunakan tanda hubung dalam nama tindakan, yang jika tidak tidak mungkin tanpa membuat rute untuk itu.

smdrager
sumber
8

Saya menganggap penting untuk disebutkan di sini bahwa atribut berikut ini juga sangat penting:

STAThreadAttribute 

Mengindikasikan bahwa model threading COM untuk suatu aplikasi adalah apartemen single-threaded apartment (STA).

Misalnya atribut ini digunakan dalam Aplikasi Formulir 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());
    }
}

Dan juga ...

SuppressMessageAttribute

Menekan pelaporan pelanggaran aturan alat analisis statis tertentu, yang memungkinkan beberapa penindasan pada artefak kode tunggal.

Sebagai contoh:

[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;
}
Eric Javier Hernandez Saura
sumber
Apakah STAThread digunakan untuk mencegah aplikasi Anda secara tidak sengaja mem-spin-off instance lain saat start up?
Luminous
7

Dari atas kepala saya, di sini adalah daftar cepat, kira-kira diurutkan berdasarkan frekuensi penggunaan, atribut yang telah ditentukan yang sebenarnya saya gunakan dalam proyek besar (~ 500k LoCs):

Bendera, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Usang, InternalVisibleTo, DebuggerStepThrough.

Eldritch Conundrum
sumber
2
+1 untuk ThreadStatic, terkejut tidak ada yang menyebutkan sejauh ini, dan juga untuk pendekatan statistik
staafl
6

Saya menghasilkan kelas entitas data melalui CodeSmith dan saya menggunakan atribut untuk beberapa rutin validasi. Berikut ini sebuah contoh:

/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
    get { return _firmGUID; }
    set { _firmGUID = value; }
}

Dan saya mendapat kelas utilitas untuk melakukan validasi berdasarkan atribut yang melekat pada kelas entitas data. Ini kodenya:

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;
    }
}
}
Ming Yeh
sumber
6

[DeploymentItem("myFile1.txt")] MSDN Doc on DeploymentItem

Ini sangat berguna jika Anda menguji file atau menggunakan file sebagai input untuk pengujian Anda.

Kevin Driedger
sumber
5

[System.Security.Permissions.PermissionSetAttribute] memungkinkan tindakan keamanan untuk PermissionSet diterapkan ke kode menggunakan keamanan deklaratif.

// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public FullConditionUITypeEditor() { }
}
CSharper
sumber