2010-01-24 44 views
7

Tôi đã có một lớp trừu tượng như thế này;Nhận loại hiện tại theo phương pháp tĩnh, chung?

public abstract PropertyBase 
{ 
    public static System.Type GetMyType() 
    { 
     return !!!SOME MAGIC HERE!!! 
    } 
} 

Tôi muốn phân lớp và khi tôi gọi GetMyType() tĩnh, tôi muốn trả về loại của lớp con. Vì vậy, nếu tôi tuyên bố một loại phụ;

public class ConcreteProperty: PropertyBase {} 

sau đó khi tôi gọi

var typeName = ConcreteProperty.GetMyType().Name; 

Tôi hy vọng 'typeName' được thiết lập để "ConcreteProperty." Tôi nghi ngờ không có cách nào để làm điều đó, nhưng tôi quan tâm nếu có ai đó biết cách để có được thông tin này.

(Các vấn đề cụ thể tôi đang cố gắng để giải quyết là tính cách rườm rà của tài sản phụ thuộc trong WPF, tôi rất muốn có thể làm một cái gì đó như thế này;

class NamedObject : DependencyObject 
{ 
    // declare a name property as a type, not an instance. 
    private class NameProperty : PropertyBase<string, NamedObject> { } 

    // call static methods on the class to read the property 
    public string Name 
    { 
     get { return NameProperty.Get(this); } 
     set { NameProperty.Set(this, value); } 
    } 
} 

Và tôi gần có một thực hiện, nhưng tôi có thể không hoàn toàn nhận được thông tin tôi cần ra khỏi lớp NameProperty của tôi)

+0

Lý do để tĩnh là gì? Được khai báo là ảo hoặc trừu tượng, bạn sẽ gặp sự cố –

+0

TẠI SAO TUYỆT VỜI: Đó là góc lẻ và một C# không thực sự được thiết kế cho. Đôi khi loại của bạn chỉ có thể có một giá trị. Vì vậy, 'lớp Steve: Person {}' khai báo một kiểu, nhưng vì chỉ có một giá trị có thể, lớp 'Steve' cũng xác định một cá thể. Tuyên bố loại 'Steve' tuyên bố đơn 'Steve'. WPF DP là như thế này; họ không thể quyết định xem chúng là dữ liệu cá thể, siêu dữ liệu hay các loại. Tôi đang cố gắng gấp tất cả chúng thành một cấu trúc mã. Đó là tất cả các máy ATM đầu cơ, nhưng tôi quan tâm đến việc theo đuổi nó vì lợi ích riêng của nó. –

+0

Đây là lý do tại sao tôi cần điều này: Tạo một lớp một phần cho mã TypeDescriptor soạn sẵn. Tên thuộc tính được tạo động không thể xung đột với các thuộc tính được định nghĩa trên loại, vì vậy tôi cần danh sách các tên thuộc tính bên trong loại để thực hiện kiểm tra. Đây là mã soạn sẵn nhiều hơn và do đó đi trong codegen. Nó cũng là một ứng cử viên hoàn hảo cho tĩnh, vì nó không thay đổi.Vì vậy, tôi cần tạo một danh sách chứa các thuộc tính của kiểu hiện tại bên trong một hàm tạo tĩnh. Vâng, địa ngục, bây giờ tôi cần phải sử dụng dây ma thuật trong mẫu T4. – Will

Trả lời

6

Bạn có thể đạt được một phần (1 cấp thừa kế sâu) sử dụng Generics:.

class PropertyBase<T> 
{ 
    public static Type GetMyType() { return typeof (T); } 
} 

// the base class is actually a generic specialized by the derived class type 
class ConcreteProperty : PropertyBase<ConcreteProperty> { /* more code here */ } 

// t == typeof(ConcreteProperty) 
var t = ConcreteProperty.GetMyType(); 
+0

Lưu ý rằng điều này chỉ hoạt động một cấp, nếu bạn xuống từ ConcreteProperty, nó sẽ vẫn trả về ConcreteProperty từ GetMyType. –

+0

Điều đó đúng. Và một trong những hạn chế của phương pháp này. Nhưng nó vẫn có thể giúp với ví dụ tài sản phụ thuộc của OP. – LBushkin

+0

Đây chắc chắn là cách tiếp cận tốt nhất mà tôi đã thấy cho đến nay; bạn tạo tham chiếu đến loại được trích dẫn lại nó trong các tham số kiểu. Đối với ví dụ của tôi, điều này làm việc độc đáo, mặc dù nó áp đặt một chút gõ trên nhà phát triển. Dù sao, đây là tốt nhất chưa, và rất hữu ích. Cảm ơn. –

4

Bit phân lớp sẽ không hoạt động, bởi vì một phương thức tĩnh được gắn với một kiểu. Đây là phương thức của loại, không phải là phương pháp của một phiên bản. Loại phụ không chứa các phương thức tĩnh của một kiểu cơ sở, vì chúng là các kiểu khác nhau và phương thức tĩnh được gắn với kiểu cơ sở. Mặc dù trình biên dịch có thể cho phép bạn gọi một phương thức tĩnh của một lớp cơ sở như thông qua một lớp dẫn xuất, nó sẽ thực tế gọi phương thức từ lớp cơ sở. Nó chỉ là đường cú pháp. Vì lý do tương tự, bạn không thể "ghi đè" các phương thức tĩnh trong các lớp con bởi vì nó sẽ có ý nghĩa rất ít.

0

Chỉ cần tự hỏi tại sao cần phải làm điều gì đó như thế này?

var typeName = ConcreteProperty.GetMyType().Name; 

Nhưng dù sao bạn biết loại khi gọi phương pháp này, bạn chỉ có thể làm được điều này cũng ..

var typeName = typeof(ConcreteProperty).Name; 

Chỉ trong trường hợp bạn cần phải làm điều này, bạn có thể sử dụng "shadowing" để ghi đè việc thực hiện lớp cơ sở trong lớp con.

public class ConcreteProperty : PropertyBase { 

     public new static Type GetMyType { 
      //provide a new implementation here 
     } 
    } 
+0

Thật không may trong mã ví dụ của tôi tôi đã đơn giản hóa nó để giảm nó thành vấn đề thiết yếu, và điều này sẽ được giải quyết theo cách bạn đã mô tả. Tuy nhiên, giải pháp của tôi yêu cầu là khả năng hỏi, đối với bất kỳ lớp con nào của PropertyBase, 'loại thực tế của bạn' là gì. Cách mà, ví dụ, gọi 'this.GetType()' luôn luôn nhận được loại thực tế chứ không phải là một loại cơ sở. –

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