2009-12-03 38 views
5

Nếu không có bất kỳ mã nào trong các lớp con, tôi muốn một lớp trừu tượng có một bản sao khác của một biến tĩnh cho mỗi lớp con. Trong C#Tạo một siêu lớp có một biến tĩnh khác nhau cho mỗi phân lớp trong C#

abstract class ClassA 
{ 
    static string theValue; 

    // just to demonstrate 
    public string GetValue() 
    { 
     return theValue; 
    } 
    ... 
} 
class ClassB : ClassA { } 
class ClassC : ClassA { } 

và (ví dụ):

(new ClassB()).GetValue(); // returns "Banana" 
(new ClassC()).GetValue(); // returns "Coconut" 

giải pháp hiện tại của tôi là thế này:

abstract class ClassA 
{ 
    static Dictionary<Type, string> theValue; 
    public string GetValue() 
    { 
     return theValue[this.GetType()]; 
    } 
    ... 
} 

Trong khi điều này hoạt động tốt, tôi tự hỏi nếu có một thanh lịch hơn hoặc được xây dựng trong cách làm điều này?

này tương tự như Can I have different copies of a static variable for each different type of inheriting class, nhưng tôi không có kiểm soát đối với các lớp con

+0

Bạn có thể làm điều đó bằng cách hack một 'Dictionary 'và gọi' GetType() ', nhưng nó sẽ rất kinh khủng ... –

+0

Đối với các thành viên tĩnh ảo/trừu tượng đó sẽ tốt đẹp. xem (tìm kiếm "thành viên tĩnh ảo") – VolkerK

+0

tại sao không chỉ làm cho nó KHÔNG tĩnh? – BlackTigerX

Trả lời

5

Trong khi điều này hoạt động tốt, tôi tự hỏi nếu có một cách thanh lịch hơn hoặc built-in để làm điều này?

Không thực sự có cách tích hợp để thực hiện việc này, vì bạn đang vi phạm nguyên tắc cơ bản về OO tại đây. Lớp cơ sở của bạn sẽ không có kiến ​​thức về các lớp con trong lý thuyết hướng đối tượng truyền thống.

Điều đó đang được nói, nếu bạn phải làm điều này, việc triển khai của bạn có thể là tốt như bạn sẽ nhận được, trừ khi bạn có thể thêm một số thông tin khác cho các lớp con trực tiếp. Nếu bạn cần kiểm soát điều này, và bạn không thể thay đổi các lớp con, điều này có lẽ sẽ là cách tiếp cận tốt nhất của bạn.

0

Có một giải pháp thay thế mà có thể hoặc không có thể là tốt hơn so với bạn, tùy thuộc vào trường hợp sử dụng:

abstract class ClassA 
{ 
    private static class InternalClass<T> { 
     public static string Value; 
    } 
    public string GetValue() 
    { 
     return (string)typeof(InternalClass<>) 
       .MakeGenericType(GetType()) 
       .GetField("Value", BindingFlags.Public | BindingFlags.Static) 
       .GetValue(null); 
    } 
} 

Cách tiếp cận này được sử dụng trong EqualityComparer<T>.Default. Tất nhiên, nó không được sử dụng cho vấn đề này. Bạn thực sự nên xem xét làm cho trừu tượng GetValue và ghi đè nó trong mỗi lớp dẫn xuất.

+0

Ông đã đề cập rằng ông không thể ghi đè GetValue trong mỗi lớp dẫn xuất ... – enorl76

+0

@ enorl76 Câu hỏi này rất cũ nên tôi không nhớ lại bối cảnh thực tế, nhưng tôi không nghĩ cách tiếp cận này đòi hỏi GetValue trọng yếu. Câu cuối cùng của câu trả lời của tôi chỉ là một bình luận về cách tiếp cận đúng, không phải là một phần của giải pháp. –

1

Đây là một chút khác biệt so với những gì bạn đang yêu cầu, nhưng có thể hoàn thành điều tương tự.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine((new B()).theValue); 
     Console.WriteLine((new C()).theValue); 
     Console.ReadKey(); 
    } 
} 

public abstract class A 
{ 
    public readonly string theValue; 

    protected A(string s) 
    { 
     theValue = s; 
    } 
} 

public class B : A 
{ 
    public B(): base("Banana") 
    { 
    } 
} 

public class C : A 
{ 
    public C(): base("Coconut") 
    { 
    } 
} 
+0

Đó là cách hiển nhiên + tốt nhất - không may là tôi không thể thay đổi các lớp B & C – ste

1

Điều này thì sao?



    class Base { 
    protected static SomeObjectType myVariable; 

    protected void doSomething() 
    { 
    Console.WriteLine(myVariable.SomeProperty); 
    } 
    } 

    class AAA : Base 
    { 
    static AAA() 
    { 
    myVariable = new SomeObjectType(); 
    myVariable.SomeProperty = "A"; 
    } 
    } 

    class BBB : Base 
    { 
    static BBB() 
    { 
    myVariable = new SomeObjectType(); 
    myVariable.SomeProperty = "B"; 
    } 
    } 

Nó phù hợp với tôi. Sẽ đẹp hơn với Giao diện.

+0

Chăm sóc để giải thích mã là gì vì lợi ích của người khác, một đoạn mã không giải thích sẽ không thỏa mãn người dùng SO :) – t0mm13b

+3

Không, điều này sẽ Không bao giờ làm việc. Tùy thuộc vào khi VM thấy các kiểu, đó là khi hàm dựng tĩnh sẽ được gọi, và do đó 'myVariable' sẽ chứa giá trị cuối cùng của hàm khởi tạo-static-constructor. Và thậm chí tệ hơn, nó sẽ không xác định ai là người xây dựng cuối cùng sẽ là. – enorl76

Các vấn đề liên quan