Các thuộc tính hữu ích nhất [đã đóng]


784

Tôi biết rằng các thuộc tính là vô cùng hữu ích. Có một số cái được xác định trước như [Browsable(false)]cho phép bạn ẩn các thuộc tính trong tab thuộc tính. Đây là một câu hỏi hay giải thích các thuộc tính: Thuộc tính trong .NET là gì?

Các thuộc tính được xác định trước (và không gian tên của chúng) bạn thực sự sử dụng trong các dự án của bạn là gì?


27
Câu hỏi gì? , toàn bộ trang tràn ngập những câu trả lời hay với những lời giải thích tuyệt vời. Trong khi tôi đọc qua điều này, tôi đã có kinh nghiệm như phỏng vấn nhiều chuyên gia về quan điểm của họ. +100 cho câu hỏi.
Muthu Ganapathy Nathan

Tôi đồng ý, những câu hỏi như thế này là một trong những câu hỏi có giá trị nhất - làm cho SO ít hữu ích hơn khi nó bị đóng.
David Thielen

Câu trả lời:


669

[DebuggerDisplay]có thể thực sự hữu ích để nhanh chóng xem đầu ra tùy chỉnh của Loại khi bạn di chuột qua thể hiện của Loại trong khi gỡ lỗi. thí dụ:

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

Đây là cách nó sẽ tìm trong trình gỡ lỗi:

văn bản thay thế

Ngoài ra, điều đáng nói là [WebMethod]thuộc tính đó với CacheDurationtập thuộc tính có thể tránh việc thực thi phương thức dịch vụ web không cần thiết.


62
Wow, thật sự rất tốt để biết. Tôi thường hoàn thành điều tương tự bằng cách ghi đè ToString, nhưng điều này tốt hơn.
Brian

17
Hãy cẩn thận với điều này, nó cắn khối CPU lớn hơn nhiều so với ToString.
Nikola Radosavljević

1
Bạn cũng có thể sử dụng điều này để hiển thị kết quả của các phương thức. Điều này có thể tạo ra trải nghiệm gỡ lỗi khá khó hiểu nếu phương thức (hoặc property-get) có tác dụng phụ.
Øyvind Skaar

4
@ NikolaRadosavljević nó sẽ chỉ chiếm năng lượng CPU trong quá trình gỡ lỗi
Nickolay Kondratyev

2
@Nickolay Kondratyev: Tôi không biết tất cả mọi thứ, nhưng bạn có thể xem qua các thực tiễn tốt nhất về dịch vụ web có thể đưa bạn đến một số kết luận: blog.msdn.com/b/jaredpar/archive/2011/03/ 18 /
Lọ

273

System.Obsoletetheo tôi là một trong những thuộc tính hữu ích nhất trong khung. Khả năng đưa ra cảnh báo về mã không còn được sử dụng là rất hữu ích. Tôi thích có một cách để nói với các nhà phát triển rằng một cái gì đó không còn được sử dụng, cũng như có một cách để giải thích tại sao và chỉ ra cách tốt hơn / mới để làm một cái gì đó.

Conditional attributecũng khá tiện dụng cho việc sử dụng gỡ lỗi. Nó cho phép bạn thêm các phương thức trong mã của mình cho các mục đích gỡ lỗi sẽ không được biên dịch khi bạn xây dựng giải pháp để phát hành.

Sau đó, có rất nhiều thuộc tính dành riêng cho Điều khiển web mà tôi thấy hữu ích, nhưng những thuộc tính đó cụ thể hơn và không có bất kỳ việc sử dụng nào ngoài việc phát triển các điều khiển máy chủ từ những gì tôi đã tìm thấy.


50
Bạn có thể chuyển "true" thành một trong các tham số cho System.Obsolete khiến cảnh báo trở thành lỗi do đó phá vỡ bản dựng. Rõ ràng điều này nên được thực hiện một khi bạn đã dọn sạch tất cả các cảnh báo. :)
Adrian Clark

14
Khi bạn xóa tất cả các cảnh báo, sẽ tốt hơn nếu chỉ xóa phương thức?
Pedro

10
@Pedro: Đôi khi bạn không thể vì lý do tương thích ngược. Nếu nó là riêng tư và không sử dụng, yeah, xóa nó.
Fantius

3
@plinth Ném một ngoại lệ sẽ là một ý tưởng tồi vì nhiều lý do, # 1 là lý do chính để sử dụng Lỗi thời () là để bạn có thể giữ mã được biên dịch hoạt động trong khi ở giai đoạn chuyển tiếp. Nếu bạn không cho phép bất cứ ai gọi phương thức, tại sao không xóa nó?
Dan Herbert

17
@plinth Đó là để ngăn chặn mã mới sử dụng phương thức. Mã cũ sẽ vẫn tương thích nhị phân nếu một phương thức được đánh dấu lỗi thời, nhưng nó sẽ ngừng hoạt động nếu bạn ném một ngoại lệ. Nếu ai đó đang sử dụng sự phản chiếu để đi xung quanh lá cờ "Obsolte", thì bạn sẽ gặp vấn đề tồi tệ hơn ...
Dan Herbert

204

[Flags]là khá tiện dụng. Cú pháp đường để chắc chắn, nhưng vẫn khá đẹp.

[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 chỉ ra điều mà tôi chưa nhận ra và điều đó làm giảm bớt sự nhiệt tình của tôi đối với thuộc tính này: nó không hướng dẫn trình biên dịch cho phép các tổ hợp bit làm giá trị hợp lệ cho các biến liệt kê, trình biên dịch cho phép điều này cho phép liệt kê bất kể. Nền C ++ của tôi hiển thị qua ... thở dài


Vậy chính xác thì thuộc tính Flags làm gì?
Andrei Rînea

13
Tôi hy vọng các bạn nhận ra thuộc tính Flags làm bugger tất cả. Nó hoàn toàn không cần thiết / được sử dụng, ngoại trừ TypeConverter.
leppie

3
@leppie: ToString () cũng vậy. Nhưng ... wow. Vì một số lý do, tôi đã mong đợi hành vi của các phép liệt kê mà không có thuộc tính giống như C ++: các giá trị or'd tạo ra một số nguyên (không thể được chuyển như là phương thức mong đợi enum param). Tôi thấy bây giờ không phải là trường hợp. Yếu ... ok, .NET enum hút.
Shog9

2
[Cờ] thực sự chỉ giúp trình gỡ lỗi và các hàm .ToString () biết rằng một giá trị có khả năng là sự kết hợp của một số khai báo trong enum. Tôi không chắc chắn, nó có thể giúp Intellisense giúp bạn sử dụng enum hiệu quả hơn.
Kenzi

31
[Flags]không có công dụng lớn hơn là chỉ là đường cú pháp. Trong khi sử dụng các dịch vụ web, việc tuần tự hóa / khử tuần tự hóa sẽ không hoạt động nếu giá trị như SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamđược thông qua. Không có [Flags]thuộc tính, trình giải mã sẽ không biết rằng giá trị có thể là sự kết hợp của các cờ. Đã học được điều này một cách khó khăn sau khi dành khoảng hai ngày để suy nghĩ tại sao WCF của tôi không hoạt động.
Neo

177

Tôi thích [DebuggerStepThrough]từ System.Diagnostics .

Rất thuận tiện để tránh bước vào các phương thức hoặc thuộc tính không có gì một dòng đó (nếu bạn buộc phải làm việc sớm .Net mà không có thuộc tính tự động). Đặt thuộc tính trên một phương thức ngắn hoặc getter hoặc setter của một thuộc tính và bạn sẽ bay ngay bằng cách nhấn "bước vào" trong trình gỡ lỗi.


5
Vì vậy, nhiều lần tôi ước tôi biết về khách sạn này
waser

1
Chỉ là một sự xấu hổ khi nó bị phá vỡ với việc đóng cửa - xem gregbeech.com/bloss/tech/archive/2008/10/17/ cho để biết thêm thông tin.
Greg Beech

3
Cũng hữu ích cho bất kỳ Mã WM_Paint nào mà bạn biết hoạt động :)
Pondidum

@GregB336 URL đó trả về lỗi .NET. Đẳng cấp! :)
smdrager

@smdrager - Phải là một vấn đề tạm thời, dường như làm việc cho tôi ngày hôm nay.
Greg Beech

135

Để biết giá trị của nó, đây là danh sách tất cả các thuộc tính .NET . Có vài trăm.

Tôi không biết về ai khác nhưng tôi có một số RTFM nghiêm túc để làm!


33
danh sách đã đăng là dành cho .net 1.1 ở đây là danh sách dành cho 3,5 msdn.microsoft.com/en-us/l
Library / system.attribution.aspx

2
Cập nhật các liên kết trong câu hỏi. Bây giờ nó là danh sách đầy đủ cho 3,5
R. Martinho Fernandes

8
Trên thực tế, liên kết đến mới nhất, không phải 3,5 cụ thể.
Brian Ortiz

1
Bây giờ nếu chỉ có danh sách không chỉ là một danh sách các liên kết, mà là tên và mô tả. Ồ tốt @BrianOrtiz đã đúng. Danh sách này ở phiên bản 4.5.
Sáng

Bạn chỉ cần thay đổi khung bạn đang nhắm mục tiêu ở trên cùng với thông báo "Phiên bản khác".
Novaterata 6/2/2015

129

Phiếu bầu của tôi sẽ dành cho Conditional

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

Bạn có thể sử dụng điều này để thêm một chức năng với các tính năng sửa lỗi nâng cao; giống như Debug.Write, nó chỉ được gọi trong các bản dựng gỡ lỗi và do đó cho phép bạn gói gọn logic gỡ lỗi phức tạp bên ngoài luồng chính của chương trình.


5
không phải điều này giống như làm #if DEBUG sao?
Neil N

10
Một phần nào đó, #if DEBUG có nghĩa là người gọi cũng không được gọi nó, trong khi Conditioinal rời khỏi cuộc gọi nhưng làm cho nó trở thành một NOP bị loại bỏ tại JIT.
Rangoric

23
Ngoài ra, bạn thường sử dụng #if DEBUG xung quanh các cuộc gọi và [Có điều kiện] xung quanh các phương thức . Vì vậy, nếu bạn gọi một phương thức sửa lỗi 100 lần, tắt nó là vấn đề thay đổi mã đơn lẻ, không phải 100.
Steve Cooper

13
Nhận xét của Rangoric là sai một cách tinh tế (ít nhất là đối với C #): phương pháp được bao gồm không thay đổi; trang web cuộc gọi bị bỏ qua. Điều này có một vài hàm ý: các tham số không được đánh giá và phương thức có điều kiện được chứa, không thay đổi, trong đầu ra của trình biên dịch. Bạn có thể xác minh điều này với sự phản ánh. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/...
Đánh dấu Sowul

97

Tôi luôn luôn sử dụng DisplayName, DescriptionDefaultValuecác thuộc tính trên tài sản công cộng của người dùng điều khiển, điều khiển tùy chỉnh của tôi hay bất kỳ lớp tôi sẽ chỉnh sửa thông qua một mạng lưới tài sản. Các thẻ này được .NET PropertyGrid sử dụng để định dạng tên, bảng mô tả và in đậm các giá trị không được đặt thành các giá trị mặc định.

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

Tôi chỉ muốn IntelliSense của Visual Studio sẽ đưa Descriptionthuộc tính vào tài khoản nếu không tìm thấy bình luận XML nào. Nó sẽ tránh phải lặp lại cùng một câu hai lần.


3
Không thể tin rằng không ai chỉ ra Descriptioncho đến khi bạn .. Nó hữu ích nhất đối với tôi khi được sử dụng với enums ..
nawfal

68

[Serializable]được sử dụng tất cả thời gian để tuần tự hóa và giải tuần tự hóa các đối tượng đến và từ các nguồn dữ liệu ngoài như xml hoặc từ một máy chủ từ xa. Thêm về nó ở đây.


Nó thực sự được đề cập đến một psuedoattribution, vì C # phát ra một cờ siêu dữ liệu cho [Nối tiếp], không phải là một thể hiện thuộc tính tùy chỉnh;)
TraumaPony

1
Trong khi rất hữu ích [Nối tiếp] không hoàn hảo. Nó đòi hỏi quá nhiều sự mày mò và thử nghiệm và lỗi để có được kết quả bạn muốn.
shoosh

Tôi sẽ thứ hai shoosh!
John Bubriski

System.NonSerializedAttribution rất hữu ích nếu bạn muốn kiểm soát nhiều hơn đối với việc xê-ri hóa tự động.
CSharper

Như một lưu ý phụ, tôi sẽ nói thêm rằng hiệu suất của việc xê-ri hóa .Net tích hợp khá kém, như chậm hơn 2 hoặc 3 bậc so với mã thủ công.
redcalx

57

Theo tinh thần của Hofstadt, [Attribute]thuộc tính này rất hữu ích, vì đó là cách bạn tạo các thuộc tính của riêng mình. Tôi đã sử dụng các thuộc tính thay vì giao diện để triển khai các hệ thống plugin, thêm mô tả vào Enums, mô phỏng nhiều công văn và các thủ thuật khác.


13
Nghe hay đấy! Bạn có phiền hiển thị một số ví dụ về hệ thống plugin và mô tả enum không? Đó là cả hai điều tôi quan tâm khi thực hiện bản thân mình!
John Bubriski

46

Đây là bài viết về thuộc tính thú vị InternalsVisibleTo . Về cơ bản những gì nó làm bắt chước chức năng truy cập bạn bè C ++. Nó rất tiện dụng để thử nghiệm đơn vị.


7
Bạn không có nghĩa là tiện dụng để hack một bài kiểm tra đơn vị trên một cái gì đó không thể / không nên thử nghiệm?
the_drow

@the_drow: Bạn nói về 'người truy cập riêng tư': msdn.microsoft.com/en-us/l
Library / ms184807% 28v = vs.80% 29.aspx

@habakuk: Không hẳn. Có những trường hợp các lớp bên trong nên được đưa ra để thử nghiệm đơn vị, thường là do thiết kế xấu.
the_drow

2
@the_drow: Tôi sẽ không nói rằng InternalsVisibleTo là xấu cho thử nghiệm đơn vị; bạn có thể tạo và kiểm tra các "đơn vị" nhỏ hơn không thể nhìn thấy bên ngoài dự án của bạn (nó giúp bạn có một api sạch và nhỏ). Nhưng nếu bạn cần 'người truy cập riêng' để kiểm tra đơn vị thì có lẽ có gì đó không đúng.
habakuk

10
@the_drow Tôi không đồng ý với khẳng định của bạn internalkhông công khai. Nó công khai trong hội đồng đang được thử nghiệm và nên được kiểm tra đơn vị để các lớp khác trong hội đồng có thể đảm nhận chức năng sửa lỗi của nó. Nếu bạn không kiểm tra đơn vị, bạn sẽ phải kiểm tra các chức năng của nó trong tất cả các lớp tiêu thụ.
tvanfosson


28

Tôi muốn đề xuất [TestFixture][Test]- từ thư viện nUnit .

Các bài kiểm tra đơn vị trong mã của bạn cung cấp sự an toàn trong việc tái cấu trúc và tài liệu được mã hóa.


26
[XmlIgnore]

vì điều này cho phép bạn bỏ qua (trong bất kỳ tuần tự xml nào) các đối tượng 'cha mẹ' có thể gây ra ngoại lệ khi lưu.


25

Nó không được đặt tên tốt, không được hỗ trợ tốt trong khung và không yêu cầu tham số, nhưng thuộc tính này là một điểm đánh dấu hữu ích cho các lớp không thay đổi:

[ImmutableObject(true)]

6
Theo các tài liệu, chỉ được sử dụng tại thời điểm thiết kế (không may).
Hans Ke vào

1
Cho rằng đây chỉ là thời gian thiết kế, có lẽ sẽ tốt hơn nếu tạo ImmutableObjectAttributelớp của riêng bạn - ít nhất bạn có thể loại bỏ tham số.
Roy Tinker

25

Tôi thích sử dụng [ThreadStatic]thuộc tính kết hợp với lập trình dựa trên chủ đề và ngăn xếp. Ví dụ: nếu tôi muốn một giá trị mà tôi muốn chia sẻ với phần còn lại của chuỗi cuộc gọi, nhưng tôi muốn thực hiện nó ngoài băng tần (tức là bên ngoài các tham số cuộc gọi), tôi có thể sử dụng một cái gì đó như thế này.

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

Sau này trong mã của tôi, tôi có thể sử dụng điều này để cung cấp thông tin theo ngữ cảnh ngoài băng cho những người hạ nguồn từ mã của tôi. Thí dụ:

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

Thuộc tính ThreadStatic cho phép tôi chỉ phạm vi cuộc gọi đến luồng trong câu hỏi tránh vấn đề lộn xộn của việc truy cập dữ liệu trên các luồng.


và làm thế nào để truy cập sau đó? Không hiểu điểm của mẫu sử dụng của bạn ở đây. Bạn có thể giải thích?
Beachwalker

@Beachwalker Hiện tại nên tĩnh, chỉnh sửa nó ngay. Bây giờ bạn có thể truy cập MyContextInformation.Currentđể có được bối cảnh hoạt động trên ngăn xếp. Đây là một khái niệm rất tốt trong một số trường hợp nhất định, động cơ (công ty của tôi) sử dụng nó cho nhiều mục đích.
Felix K.

23

Các DebuggerHiddenAttribute cho phép để tránh bước vào mã mà không cần phải sửa lỗi.

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

Ngoài ra, nó ngăn không cho hiển thị các phương thức trong theo dõi ngăn xếp, hữu ích khi có một phương thức chỉ bao bọc một phương thức khác:

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

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

Nếu bây giờ bạn gọi GetElementAt(new Vector2(10, 10))và xảy ra lỗi tại phương thức được bao bọc, ngăn xếp cuộc gọi sẽ không hiển thị phương thức đang gọi phương thức đó sẽ ném lỗi.


21

DesignerSerializationVisibilityAttributerất hữu ích Khi bạn đặt thuộc tính thời gian chạy trên một điều khiển hoặc thành phần và bạn không muốn nhà thiết kế tuần tự hóa nó, bạn sử dụng nó như thế này:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}

4
rất hữu ích cho các thành phần WinForms. sử dụng kết hợp với [Duyệt được (sai)]
Đánh dấu Heath

3
Điểm hay - [Browsable(false)]được yêu cầu để ẩn nó khỏi người dùng của nhà thiết kế, nơi [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]được yêu cầu để nó sẽ không được nối tiếp.
cấu hình

17

Chỉ có một vài thuộc tính được hỗ trợ trình biên dịch, nhưng một cách sử dụng thuộc tính rất thú vị là trong AOP: PostSharp sử dụng các thuộc tính bespoke của bạn để đưa IL vào các phương thức, cho phép tất cả các cách của khả năng ... log / dấu vết là các ví dụ tầm thường - nhưng một số ví dụ hay khác là những thứ như triển khai INotifyPropertyChanged tự động ( tại đây ).

Một số điều đó xảy ra và tác động trực tiếp đến trình biên dịch hoặc thời gian chạy :

  • [Conditional("FOO")] - các cuộc gọi đến phương thức này (bao gồm cả đánh giá đối số) chỉ xảy ra nếu biểu tượng "FOO" được xác định trong quá trình xây dựng
  • [MethodImpl(...)] - được sử dụng để chỉ một số thứ như đồng bộ hóa, nội tuyến
  • [PrincipalPermission(...)] - được sử dụng để tự động kiểm tra bảo mật vào mã
  • [TypeForwardedTo(...)]- được sử dụng để di chuyển các loại giữa các cụm mà không cần xây dựng lại người gọi

Đối với những thứ được kiểm tra thủ công thông qua sự phản chiếu - Tôi là một fan hâm mộ lớn của các System.ComponentModelthuộc tính; những thứ như [TypeDescriptionProvider(...)], [TypeConverter(...)][Editor(...)]có thể thay đổi hoàn toàn hành vi của các loại trong các tình huống ràng buộc dữ liệu (ví dụ: thuộc tính động, v.v.).


15

Nếu tôi thực hiện thu thập thông tin mã, tôi nghĩ hai cái này sẽ đứng đầu:

 [Serializable]
 [WebMethod]

15
[WebMethod] được sử dụng để trang trí một phương thức được hiển thị trong dịch vụ web. [Nối tiếp] đánh dấu các đối tượng của bạn sao cho chúng có thể được tuần tự hóa cho các mục đích như chuyển chúng qua các miền ứng dụng.
Kev

15

Tôi đã được sử dụng [DataObjectMethod]gần đây. Nó mô tả phương thức để bạn có thể sử dụng lớp của mình với ObjectDataSource (hoặc các điều khiển khác).

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

Thêm thông tin


12

Trong dự án hiện tại của chúng tôi, chúng tôi sử dụng

[ComVisible(false)]

Nó kiểm soát khả năng truy cập của một loại hoặc thành viên được quản lý riêng lẻ hoặc của tất cả các loại trong một tổ hợp, để COM.

Thêm thông tin


12
[TypeConverter(typeof(ExpandableObjectConverter))]

Yêu cầu nhà thiết kế mở rộng các thuộc tính là các lớp (trong tầm kiểm soát của bạn)

[Obfuscation]

Hướng dẫn các công cụ obfuscation để thực hiện các hành động được chỉ định cho một hội đồng, loại hoặc thành viên. (Mặc dù thông thường bạn sử dụng cấp độ hội[assembly:ObfuscateAssemblyAttribute(true)]


1
Tôi đã đoán, nhưng đã sai. Thuộc tính Obfuscation chỉ là một gợi ý cho các obfsucators của bên thứ 3. Nó không làm cho trình biên dịch làm xáo trộn bất cứ thứ gì theo mặc định.
Dan đang loay hoay bởi Firelight

@DanNeely miễn phí cho người dùng Visual Studio Pro / Ultimate!
Chris S

4
Nếu bạn đang đề cập đến DotFuscator Community Edition, mức độ bảo vệ được cung cấp thấp đến mức tốt nhất là nó hầu như không tính bất cứ điều gì.
Dan đang loay hoay bởi Firelight

@ricovox Tôi đã thêm một bản tóm tắt
Chris S

9

Các thuộc tính tôi sử dụng nhiều nhất là các thuộc tính liên quan đến Tuần tự hóa XML.

XmlRoot

XmlElement

XmlAttribute

Vân vân...

Vô cùng hữu ích khi thực hiện bất kỳ phân tích hoặc tuần tự hóa XML nhanh và bẩn.


8

Là một nhà phát triển trung cấp tôi thích

System.ComponentModel.EditorBrowsableAttribute Cho phép tôi ẩn các thuộc tính để nhà phát triển giao diện người dùng không bị quá tải với các thuộc tính mà họ không cần phải xem.

System.ComponentModel.BindableAttributeMột số thứ không cần phải là cơ sở dữ liệu. Một lần nữa, giảm bớt công việc mà các nhà phát triển UI cần làm.

Tôi cũng thích cái DefaultValuemà Lawrence Johnston đã đề cập.

System.ComponentModel.BrowsableAttributeFlagsđược sử dụng thường xuyên.

Tôi sử dụng System.STAThreadAttribute System.ThreadStaticAttribute khi cần.

Nhân tiện. Tôi những thứ này chỉ có giá trị cho tất cả các nhà phát triển khung .Net.


8

[EditorBrowsable(EditorBrowsableState.Never)]cho phép bạn ẩn các thuộc tính và phương thức khỏi IntelliSense nếu dự án không nằm trong giải pháp của bạn. Rất hữu ích để ẩn các luồng không hợp lệ cho các giao diện trôi chảy. Tần suất bạn muốn GetHashCode () hoặc Equals ()?

Đối với MVC [ActionName("Name")]cho phép bạn có hành động Nhận và Đăng hành động với cùng chữ ký phương thức hoặc sử dụng dấu gạch ngang trong tên hành động, điều mà nếu không sẽ không thể thực hiện được nếu không tạo tuyến đường cho nó.


8

Tôi cho rằng điều quan trọng cần đề cập ở đây là các thuộc tính sau cũng rất quan trọng:

STAThreadAttribute 

Chỉ ra rằng mô hình luồng COM cho một ứng dụng là căn hộ đơn luồng (STA).

Ví dụ: thuộc tính này được sử dụng trong Ứng dụng Windows Forms:

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

Và cũng ...

SuppressMessageAttribute

Loại bỏ báo cáo về vi phạm quy tắc công cụ phân tích tĩnh cụ thể, cho phép nhiều lần triệt tiêu trên một tạo phẩm mã duy nhất.

Ví dụ:

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

STAThread có được sử dụng để ngăn ứng dụng của bạn vô tình quay vòng khỏi một phiên bản khác của chính nó khi khởi động không?
Sáng

7

Ngoài đầu tôi, đây là một danh sách nhanh, được sắp xếp theo tần suất sử dụng, các thuộc tính được xác định trước mà tôi thực sự sử dụng trong một dự án lớn (~ 500k LoCs):

Cờ, Nối tiếp, WebMethod, COMVisible, TypeConverter, có điều kiện, ThreadStatic, lỗi thời, InternalsVisibleTo, DebuggerStepTh khóa.


2
+1 cho ThreadStatic, thật ngạc nhiên khi không có ai nhắc đến nó cho đến nay, và cả về phương pháp thống kê
staafl

6

Tôi tạo lớp thực thể dữ liệu thông qua CodeSmith và tôi sử dụng các thuộc tính cho một số thói quen xác thực. Đây là một ví dụ:

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

Và tôi đã có một lớp tiện ích để thực hiện xác nhận dựa trên các thuộc tính được đính kèm với lớp thực thể dữ liệu. Đây là mã:

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


5

[System.Security.Permissions.PermissionSetAttribute] cho phép các hành động bảo mật cho Perm Permet được áp dụng cho mã bằng cách sử dụng bảo mật khai báo.

// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public FullConditionUITypeEditor() { }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.