Giao diện không thể chứa các lĩnh vực, nhưng chúng có thể chứa các thuộc tính. Trong hầu hết các trường hợp, thuộc tính có thể được sử dụng như các lĩnh vực, và không có khó khăn với câu nói:
interface ISomeProperties
{int prop1 {get;set;}; string prop2 {get; set;}}
interface IMoreProperties
{string prop3 {get;set;}; double prop4 {get; set;}}
interface ICombinedProperties : ISomeProperties, IMoreProperties;
{ }
Cho một vị trí lưu trữ của loại ICombinedProperties
, người ta có thể truy cập tất cả bốn thuộc tính trực tiếp và không ồn ào.
Tuy nhiên, cần lưu ý rằng có một vài điều có thể được thực hiện với các trường không thể thực hiện với các thuộc tính. Ví dụ: trong khi một trường có thể được chuyển đến Interlocked.Increment
thì một thuộc tính không thể; cố gắng để Interlocked.Increment
một thuộc tính bằng cách sao chép nó vào một biến, gọi Interlocked.Increment
trên đó và sau đó sao chép kết quả trở lại thuộc tính có thể "hoạt động" trong một số trường hợp, nhưng sẽ thất bại nếu hai chủ đề cố gắng thực hiện cùng một điều có thể ví dụ cho cả hai chủ đề để đọc một giá trị 5, tăng nó lên 6, và sau đó viết lại 6, trong khi có hai chủ đề gọi Interlocked.Increment
trên một trường ban đầu bằng 5 sẽ được đảm bảo mang lại 7.).
Để giải quyết vấn đề này, có thể cần có một số phương pháp thực hiện một phương thức liên khóa trên một trường (ví dụ: có thể có hàm gọi Interlocked.Increment
trên trường và trả về kết quả) và/hoặc bao gồm các chức năng mà sẽ gọi một đại biểu chỉ định với một lĩnh vực như một tham số ref
(ví dụ
delegate void ActionByRef<T1>(ref T1 p1);
delegate void ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2,T3>(ref T1 p1, ref T2 p2, ref T3 p3);
interface IThing
{ // Must allow client code to work directly with a field of type T.
void ActOnThing(ActionByRef<T> proc);
void ActOnThing<ExtraT1>(ActionByRef<T, ExtraT1> proc, ref ExtraT1 ExtraP1);
void ActOnThing<ExtraT1, ExtraT2>
(ActionByRef<T> proc, ref ExtraT1 ExtraP1, ref ExtraT2 ExtraP2);
}
với một thể hiện của giao diện, người ta có thể làm điều gì đó như:
theInstance.ActOnThing(
(ref int param) => Threading.Interlocked.Increment(ref param)
);
hay, nếu ai có biến cục bộ maskValue
và xorValue
và muốn atomically cập nhật các trường với field = (field & maskValue)^xorValue
:
theInstance.ActOnThing(
(ref int Param, ref int MaskValue, ref int XorValue) => {
int oldValue,newValue;
do {oldValue = param; newValue = (oldValue & MaskValue)^XorValue;
while (Threading.Interlocked.CompareExchange(ref Param, newValue, oldValue) !=
oldValue),
ref maskValue, ref xorValue);
);
Nếu chỉ có một vài loại hành động người ta sẽ muốn thực hiện trên các lĩnh vực, nó sẽ là đơn giản nhất để đơn giản bao gồm chúng trong giao diện. Mặt khác, cách tiếp cận được đưa ra ở trên cho phép một giao diện để lộ các trường của nó theo cách sao cho cho phép các máy khách thực hiện các chuỗi hành động tùy ý trên chúng.
Bạn có thể sử dụng bố cục. Ngoài ra còn có [mixins] (http://stackoverflow.com/questions/255553/is-it-possible-to-implement-mixins-in-c) –