簡體   English   中英

為什么 C# 不接受帶有 generics 參數的構造函數要求?

[英]Why C# don't accept constructor requirements with parameters on generics?

與 C# Generics 一起使用,您可以擁有這樣的 class:

class Foo<T> where T:new() {}

這意味着類型 T 應該有一個沒有參數的構造函數。 如果我們能有,那就太好了:

class Foo<T> where T : new(string)
{
    private T CreateItem()
    {
        string s="";
        return new T(s);
    }
}

微軟沒有將此功能添加到語言中是否有任何原因?

微軟沒有將此功能添加到語言中是否有任何原因?

您描述的功能是更通用功能“允許需要特定方法存在的約束”的特定情況。 例如,你可能會說:

void M<T>(T t) where T has an accessible method with signature double Foo(int)
{
    double x = t.Foo(123);
}

我們在 C# 中沒有該功能,因為必須通過成本效益分析來證明這些功能是合理的。 從設計和實現的角度來看,這將是一個相當昂貴的特性——這個特性不僅會推動對 C# 的需求,還會對每一種 .NET 語言提出需求。 證明該功能合理的引人注目的好處是什么?

此外:假設我們確實設計了該功能。 它將如何有效地實施 泛型類型系統中的約束經過精心設計,因此抖動可以生成有效的代碼然后可以為每個引用類型共享。 我們如何為任意方法模式匹配生成有效的代碼? 當方法的槽可以在編譯時知道時,這種高效的分派非常簡單。 有了這個功能,我們將不再有這個優勢。

您想要的功能是相同的功能,只是方法類型僅限於構造函數。

請記住,generics 的目的是讓您編寫通用類型的代碼。 如果您需要的約束比可以在類型系統中捕獲的內容更具體,那么您可能會嘗試濫用 generics。

與其嘗試猜測 Microsoft 決定采用特定實現的原因,不如使用工廠模式為您提供一種解決方法

public interface IFactory<T>
{
   T CreateItem(string s);
}

class Foo<TFactory,T> where TFactory : IFactory<T>, new()
{
    private T CreateItem()
    {
        var factory = new TFactory();
        string s="";
        return factory.CreateItem(s);
    }
}

使用這種模式,假設你有一個 class Bar ,它的構造函數采用單個字符串:

public class Bar
{
   public Bar(string laa)
   {}
}

您只需要一個實現IFactory<Bar>BarFactory

public class BarFactory : IFactory<Bar>
{
   public BarFactory () {}
   public Bar CreateItem(string s)
   {
      return new Bar(s);
   }
}

現在你可以用 Foo 使用那個工廠了

var foo = new Foo<BarFactory,Bar>(); // calls to CreateItem() will construct a Bar

當我想要一個使用 arguments 調用構造函數的通用 function 時,我采用的解決方案是使用反射來查找和調用它。

鑒於我控制了泛型以及實現它的所有類(並且這個 function 是構造這些類的唯一地方),我想我可能會更好地給這些類一個默認構造函數並添加一個 Initialize他們都實現的接口中的方法。

(通常允許將 static 方法添加到接口的解決方案是理想的。)

暫無
暫無

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

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