2008-10-01 27 views
16

Tôi có một lớp cơ sở (kém được viết) mà tôi muốn bọc trong một đối tượng proxy. Các lớp cơ sở tương tự như sau:Làm cách nào để ngăn chặn một hàm tạo cơ sở được gọi bởi một người thừa kế trong C#?

public class BaseClass : SomeOtherBase 
{ 
    public BaseClass() {} 

    public BaseClass(int someValue) {} 

    //...more code, not important here 
} 

và, proxy của tôi giống như:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy(bool fakeOut){} 
} 

Nếu không có sự "fakeOut" nhà xây dựng, các nhà xây dựng cơ sở dự kiến ​​sẽ được gọi. Tuy nhiên, với nó, tôi mong đợi nó sẽ không được gọi. Dù bằng cách nào, tôi hoặc cần một cách để không gọi bất kỳ nhà xây dựng lớp cơ sở, hoặc một số cách khác để có hiệu quả proxy này (ác) lớp.

Trả lời

18

Nếu bạn không gọi bất kỳ hàm khởi tạo nào trong lớp cơ sở, thì hàm tạo không tham số sẽ được gọi ngầm. Không có cách nào xung quanh nó, bạn không thể khởi tạo một lớp mà không có một hàm tạo được gọi.

+1

Trên thực tế, nếu bạn đọc bình luận của tôi dưới đây, có một cách, mặc dù tôi sẽ không khuyên bạn nên nó trong nhiều trường hợp. –

+0

Câu trả lời này chỉ đơn giản là sai. Đặc biệt là trong ánh sáng của câu trả lời khác. – Kobor42

6

Ít nhất phải có 1 ctor. Cách duy nhất xung quanh nó tôi thấy là ngăn chặn. Có lớp bên trong hoặc tham khảo lớp khác.

+0

Đây là con đường mang lại cho tôi nhiều kết quả nhất. Cảm ơn! – casademora

1

Tôi lo ngại rằng không phải trình tạo hàm gọi cơ sở không phải là tùy chọn.

1

Khi bạn tạo một BaseClassProxy đối tượng nó cần phải tạo ra một thể hiện của nó là lớp cơ sở, vì vậy bạn cần phải gọi constructor lớp cơ sở, những gì bạn có thể doo là chọn Mà một để gọi, như:

public BaseClassProxy (bool fakeOut) : base (10) {} 

Để gọi hàm khởi tạo thứ hai thay vì hàm đầu tiên

4

Tôi không tin bạn có thể gọi xung quanh việc gọi hàm tạo. Nhưng bạn có thể làm điều gì đó như thế này:

public class BaseClass : SomeOtherBase 
{ 
    public BaseClass() {} 

    protected virtual void Setup() 
    { 
    } 
} 

public BaseClassProxy : BaseClass 
{ 
    bool _fakeOut; 
    protected BaseClassProxy(bool fakeOut) 
    { 
     _fakeOut = fakeOut; 
     Setup(); 
    } 

    public override void Setup() 
    { 
     if(_fakeOut) 
     { 
      base.Setup(); 
     } 
     //Your other constructor code 
    } 
} 
5

Nếu những gì bạn muốn là để không gọi một trong hai constructor của lớp cha, điều này không thể được thực hiện.

Trình tạo lớp C# phải gọi các hàm tạo lớp cơ sở. Nếu bạn không gọi một cách rõ ràng, thì cơ sở() được ngụ ý. Trong ví dụ của bạn, nếu bạn không xác định mà lớp cơ sở constructor để gọi, nó cũng giống như:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy() : base() { } 
} 

Nếu bạn thích sử dụng các constructor lớp cơ sở khác, bạn có thể sử dụng:

public BaseClassProxy : BaseClass 
{ 
    public BaseClassProxy() : base(someIntValue) { } 
} 

Dù bằng cách nào, một trong hai số sẽ được gọi, rõ ràng hoặc ngầm.

0

tôi đã kết thúc làm một cái gì đó như thế này:

public class BaseClassProxy : BaseClass 
{ 
    public BaseClass BaseClass { get; private set; } 

    public virtual int MethodINeedToOverride(){} 
    public virtual string PropertyINeedToOverride() { get; protected set; } 
} 

này đã cho tôi xung quanh một số hoạt động xấu của lớp cơ sở.

+2

Hàm tạo mặc định ngầm vẫn gọi hàm tạo-tham số-ít của BaseClass. – recursive

46

Có một cách để tạo đối tượng mà không cần gọi bất kỳ nhà thầu cụ thể nào là.

Trước khi tiếp tục, hãy chắc chắn bạn muốn thực hiện theo cách này. 99% thời gian là giải pháp sai.

Đây là cách bạn làm điều đó:

FormatterServices.GetUninitializedObject(typeof(MyClass)); 

Gọi nó ở vị trí của constructor của đối tượng. Nó sẽ tạo và trả lại cho bạn một cá thể mà không cần gọi bất kỳ hàm tạo nào hoặc các trình khởi tạo trường.

Khi bạn deserialize một đối tượng trong WCF, nó sử dụng phương pháp này để tạo đối tượng. Khi điều này xảy ra, các nhà xây dựng và các bộ khởi tạo trường thậm chí không chạy.

+9

Đó là bonkers. Toàn bộ thế giới của tôi lộn ngược! – recursive

+2

Welp, đã giải quyết được vấn đề của tôi! Cố gắng tránh các cuộc gọi DB của hàm tạo của đối tượng cha khi chạy các kiểm thử đơn vị trên một lớp kế thừa. – Tarka

+2

FormatterServices.GetUninitializedObject (typeof (MyClass)); vẫn sẽ gọi các hàm tạo tĩnh, tuy nhiên. –

0

các nhà xây dựng là công khai một cách tự nhiên. không sử dụng một constructor và sử dụng một constructor khác và làm cho nó private.so bạn sẽ tạo một cá thể không có paramtersand gọi hàm đó để xây dựng cá thể đối tượng của bạn.

0

Đây là nỗ lực đầu tiên cẩu thả của tôi tại câu trả lời này. Hãy bình chọn nó và tôi sẽ chú ý hơn.

Tôi không chắc chắn những gì bạn đang cố gắng hoàn thành, nhưng có vẻ như bạn đang thiếu giao diện. Bạn có thể chọn và chọn giao diện nào phù hợp với nhu cầu của bạn. Nếu điều này là nếu để thử nghiệm, sau đó bạn sẽ sử dụng một cái gì đó như A.Fake để kiểm tra với. Nếu bạn cung cấp thêm chi tiết về những gì bạn đang cố gắng thực hiện. Tôi có thể hữu ích hơn.

public interface IExtractedFromSomeOtherBase{ 
    // this could also be an interface that the other base already implements. 
    /* extracted stuff here */ 
} 
public interface IBaseClass { 
    /* stuff */ 
} 
public interface IBaseClassProxy { 
    /* stuff */ 
} 
public class BaseClass : 
    SomeOtherBase, IExtractedFromSomeOtherBase, IBaseClass 
{ 
    public BaseClass() {} 

    public BaseClass(int someValue) {} 

    //...more code, not important here 
} 
and, my proxy resembles: 

public BaseClassProxy : BaseClass, IBaseClassProxy 
{ 
    public BaseClassProxy(bool fakeOut){} 
} 
Các vấn đề liên quan