2010-01-14 31 views
16

Tôi có một vài lớp mà tôi muốn gắn thẻ với một thuộc tính cụ thể. Tôi có hai cách tiếp cận trong tâm trí. Một liên quan đến việc sử dụng một lớp mở rộng thuộc tính. Người kia sử dụng một giao diện trống:Giao diện hoặc thuộc tính để gắn thẻ các lớp học?

Thuộc tính

public class FoodAttribute : Attribute { } 

[Food] 
public class Pizza { /* ... */ } 

[Food] 
public class Pancake { /* ... */ } 

if (obj.IsDefined(typeof(FoodAttribute), false)) { /* ... */ } 

Interface

public interface IFoodTag { } 

public class Pizza : IFoodTag { /* ... */ } 
public class Pancake : IFoodTag { /* ... */ } 

if (obj is IFoodTag) { /* ... */ } 

Tôi ngập ngừng sử dụng các thuộc tính do sử dụng của Reflection. Đồng thời, tuy nhiên, tôi do dự về việc tạo ra một giao diện trống mà chỉ thực sự phục vụ như một thẻ. Tôi đã thử nghiệm căng thẳng cả hai và chênh lệch thời gian giữa hai chỉ khoảng ba phần nghìn giây, do đó hiệu suất không bị đe dọa ở đây.

+0

chỉ tự hỏi, bạn sẽ làm gì nếu một vật thể là thức ăn? nếu giao diện IFood trống, bạn phân biệt chúng là gì? ... – serhio

+0

Nếu đối tượng là Thực phẩm, tôi sẽ trả về FoodEventArguments. Nếu đối tượng là, nói, Đồ uống, tôi sẽ trả lại DrinkEventArguments. Về cơ bản, có một lớp cơ sở chung (giả sử ConcessionStandItem) được truyền vào hàm. – Scott

+0

Xem thêm: http://blogs.msdn.com/ericlippert/archive/2009/02/02/properties-vs-attributes.aspx –

Trả lời

14

Vâng, với các thuộc tính, bạn luôn có thể tạo thuộc tính theo cách sao cho chức năng của nó không tự động lan truyền đến các loại hậu duệ.

Với giao diện, điều đó là không thể.

Tôi sẽ đi với các thuộc tính.

+0

+1, đây cũng là điểm tôi bỏ lỡ trong câu trả lời của tôi. – Restuta

+1

Microsoft cũng đề xuất nhưng họ đã phân tách từ các đề xuất của riêng họ ở một số nơi. (ví dụ: 'IRequiresSessionState' và 'IReadOnlySessionState' trong ASP.NET). –

+1

ISerializable, tôi biết. –

5

Có thể bạn đã tự trả lời câu hỏi của mình. Thuộc tính hợp lý hơn ở đây, sự phản ánh không phải là MONSTER BIG VỚI RED EYES =)

btw, bạn có thể hiển thị mã gọi, nơi bạn xác định được đánh dấu bằng loại giao diện không? Bạn không sử dụng sự phản chiếu ở đó sao?

+3

+1 cho quái vật! –

+1

Không, tôi chỉ sử dụng toán tử 'is' để kiểm tra xem đối tượng đã cho có được đánh dấu bằng giao diện hay không (xem dòng cuối cùng của ví dụ 'Giao diện'). – Scott

+0

Cảm ơn bạn, tôi thấy bây giờ. – Restuta

0

Trong trường hợp này, như bạn nói, bạn không sử dụng giao diện chính xác.

Có gì sai khi sử dụng sự phản chiếu khiến bạn có được thuộc tính? Câu trả lời thông thường là hiệu suất nhưng đó thường không phải là một vấn đề thực sự trong gần như tất cả các trường hợp.

7

Tôi sẽ phải nói cách khác. Tôi nghĩ rằng, cho ví dụ của bạn, giao diện điểm đánh dấu có ý nghĩa hơn.

Đó là vì có vẻ như rất khả năng mà bạn có thể thêm một ngày để thêm một số thành viên vào số IFood.

thiết kế của bạn bắt đầu như thế này:

interface IFood {} 

Nhưng sau đó bạn quyết định thêm một cái gì đó có:

interface IFood { 
    int Calories { get; } 
} 

Ngoài ra còn có other ways để mở rộng giao diện:

static class FoodExtensions { 
    public static void Lighten(this IFood self) { 
    self.Calories /= 2; 
    } 
} 
Các vấn đề liên quan