2010-01-13 21 views
6

Có cách nào để làm những gì classmethod thực hiện bằng Python trong C#?Classmethod kiểu Python cho C#?

Tức là, một hàm tĩnh sẽ nhận được một đối tượng Kiểu như một tham số (ẩn) theo bất kỳ lớp con nào được sử dụng.

Một ví dụ về những gì tôi muốn, xấp xỉ, là

class Base: 
    @classmethod 
    def get(cls, id): 
     print "Would instantiate a new %r with ID %d."%(cls, id) 

class Puppy(Base): 
    pass 

class Kitten(Base): 
    pass 

p = Puppy.get(1) 
k = Kitten.get(1) 

sản lượng dự kiến ​​là

Would instantiate a new <class __main__.Puppy at 0x403533ec> with ID 1. 
Would instantiate a new <class __main__.Kitten at 0x4035341c> with ID 1. 

(same code on codepad here.)

Trả lời

1

Về nguyên tắc, bạn có thể viết một cái gì đó như thế này:

class Base 
{ 
    public static T Get<T>(int id) 
     where T : Base, new() 
    { 
     return new T() { ID = id }; 
    } 

    public int ID { get; set; } 
} 

Sau đó, bạn có thể viết var p = Base.Get<Puppy>(10). Hoặc, nếu bạn cảm thấy sợ hãi, bạn có thể viết Puppy.Get<Puppy>(10) hoặc thậm chí Kitty.Get<Puppy>;) Trong mọi trường hợp, bạn phải chuyển loại một cách rõ ràng, không ngầm.

Ngoài ra, công trình này quá:

class Base<T> where T : Base<T>, new() 
{ 
    public static T Get(int id) 
    { 
     return new T() { ID = id }; 
    } 

    public int ID { get; set; } 
} 

class Puppy : Base<Puppy> 
{ 
} 

class Kitten : Base<Kitten> 
{ 
} 

Bạn vẫn cần phải vượt qua các loại trở lên đến các lớp cơ sở, cho phép bạn để viết Puppy.Get(10) như mong đợi.

Nhưng vẫn còn, có lý do để viết nó như thế khi var p = new Puppy(10) chỉ là súc tích và thành ngữ hơn? Chắc là không.

2

Tùy thuộc vào bối cảnh, bạn có muốn Generics hoặc các phương pháp ảo.

0

Điều này tương đương với các phương thức lớp trong Object Pascal. (a. Net thực hiện sẽ là oxygene của RemObject).

Tuy nhiên, trong khi tham chiếu lớp và do đó các phương thức lớp ảo hoặc các phương pháp có vẻ tĩnh mà có thể truy cập một số trạng thái cấp lớp là tốt trong nền tảng ban đầu, tôi không nghĩ chúng có ý nghĩa nhiều đối với .Net hoặc C#.

Tôi từng sử dụng chương trình ở Oxygene trong nhiều năm và tôi không bao giờ cần tham chiếu lớp học.

Không phải vì tôi không biết cách sử dụng chúng. Trong nền tảng "gốc" ObjectPascal, bản gốc Delphi, tôi đã sử dụng chúng tất cả thời gian. Nhưng vì .Net và BCL không có hỗ trợ thực sự cho chúng nên bạn không có bất kỳ lợi thế nào bằng cách sử dụng chúng. Trong khi các nền tảng như python hoặc bản địa Delphi hỗ trợ chúng trong thư viện của họ.

Bạn rõ ràng không muốn một phương pháp tĩnh, những gì bạn muốn là cái gì đó có thể có nhà nước và/hoặc hỗ trợ thừa kế. Vì vậy, cả hai nhà máy, hoặc trong trường hợp của bạn một nhà xây dựng có thể được tốt là tốt.

0

Vì C# được biên dịch tĩnh, một cuộc gọi đến Puppy.get() được giải quyết tại thời gian biên dịch, ví dụ: nó được biết là trỏ đến Base.get() và điều đó có nghĩa là CIL được tạo (Ngôn ngữ trung gian chung) sẽ có hướng dẫn cuộc gọi đến Base.get():

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    // Code size  9 (0x9) 
    .maxstack 8 
    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: call  void Base::get(int32) 
    IL_0007: nop 
    IL_0008: ret 
} 
Các vấn đề liên quan