簡體   English   中英

是否可以約束實現接口的類的構造函數?

[英]Is it possible to constrain the constructors of classes implementing an interface?

是否可以設置所有實現接口的類都必須具有例如空構造函數的約束? 就像泛型where T : new()約束一樣?

否-不可能在給定接口的派生類或實現上施加任何此類約束。

無論如何,這樣的約束通常不是一個特別好的主意/有用,因為通常在使用接口時,您通常使用的是實現該接口的對象實例,在這種情況下,對象自然已經被創建,並且這樣的約束是多余的。 (當然是泛型的例外,在這種情況下,您可以使用new()約束)。

我的猜測是,您正在嘗試創建某種插件系統,並希望限制插件接口的實現以具有一些可用於實例化的默認構造函數...如果是這種情況,那么通常會有更好的選擇可以使用,例如MEF

您能否詳細說明為什么確實需要此功能?

不,沒有那樣的東西。 鑒於接口的常規用法是使用接口的代碼不必關心實例化的方式,所以它們有點奇怪-他們不必關心實現類是什么,而只關心它實現了接口。

如果對此有特殊用途,我建議您為此編寫單元測試-如果所有實現都在同一個程序集中,則這樣做應該非常簡單,並且幾乎會在同時捕獲任何錯誤編譯時...

我只有四種方法可以想到,在運行時可能會給您一個類,而在編譯時卻不知道。 可能會給您提供一個實現接口的對象的實例,並想產生一個類似的對象。 最好通過使接口包含NewSimilarInstance()方法來處理這種情況。 您可能在某個類中有一個方法,該方法傳遞了一個通用類型參數,該參數被限制在您的接口上。 在這種情況下,接受通用參數的例程可能具有new()約束。 否則,可以為您提供.net System.Type對象或該類型的其他某種表示形式(例如字符串)。 在后兩種情況下,沒有任何編譯時驗證將有意義。 使用類型做任何事情都需要Reflection,因此您也可以使用Reflection查看它們是否允許創建新實例。

我認為您需要為此使用虛擬類。

正如Justin所說,不僅不能使用接口約束構造函數簽名,而且不能使用抽象類約束。 也許如果您能解釋為什么需要施加這樣的約束,我們可以為您的問題找到其他解決方案

將Factory注入可以實例化您的接口的通用類,並刪除new()約束。

就像是:

public interface IFactory<out T>
{
    T CreateInstance();
}

public class GenericClass<T>
{
     private readonly IFactory<T> _factory;

     public GenericClass(IFactory<T> factory)
     {
          _factory = factory;
     }

     public DoSomething()
     {
          //...
          T foo = _factory.CreateInstance();
          //...
     }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM