簡體   English   中英

是否支持非泛型類中的泛型構造函數?

[英]Is generic constructor in non-generic class supported?

不支持,是否支持,但是我必須做一些技巧?

例:

class Foo
{
  public Foo<T1,T2>(Func<T1,T2> f1,Func<T2,T1> f2)
  {
     ...
  }
}

泛型僅在構造函數中使用,沒有字段/屬性依賴於它們,我使用它(泛型)來強制f1和f2的類型相關。

備注 :我找到了解決方法-靜態方法Create,但是無論如何,我很好奇為什么直接方法有問題。

不,通用或非通用類都不支持通用構造函數。 同樣,不支持通用事件,屬性和終結器。

只是偶爾我同意這會很方便-但語法看起來很糟糕。 例如,假設您有:

public class Foo<T> {}

public class Foo
{
    public Foo<T>() {}
}

什么會

new Foo<string>()

做? 調用非泛型類的泛型構造函數,還是泛型類的普通構造函數? 您必須以某種方式區分它們,這會很麻煩:(

同樣,請考慮泛型類中的泛型構造函數:

public class Foo<TClass>
{
    public Foo<TConstructor>() {}
}

您如何稱呼構造函數? 希望我們都同意:

new Foo<string><int>()

太可怕了...

因此,是的,從語義上講,它偶爾會有用-但不幸的是,由此產生的丑陋抵消了這種平衡。

不支持泛型構造函數,但是您可以通過簡單地定義一個泛型, static方法返回新的Foo

class Foo
{
  public static Foo CreateFromFuncs<T1,T2>(Func<T1,T2> f1,Func<T2,T1> f2)
  {
     ...
  }
}

像這樣使用:

// create generic dependencies
var func1 = new Func<byte, string>(...);
var func2 = new Func<string, byte>(...);

// create nongeneric Foo from dependencies
Foo myFoo = Foo.CreateFromFuncs<byte, string>(func1, func2);

這是一個有關如何希望具有額外的構造函數類型參數的實用示例,以及解決方法。

我將為IDisposable引入一個簡單的RefCounted包裝器:

public class RefCounted<T> where T : IDisposable
{
    public RefCounted(T value)
    {
        innerValue = value;
        refCount = 1;
    }

    public void AddRef()
    {
        Interlocked.Increment(ref refCount);
    }

    public void Dispose()
    {
        if(InterlockedDecrement(ref refCount)<=0)
            innerValue.Dispose();
    }

    private int refCount;
    private readonly innerValue;
}

這似乎很好。 但是遲早您希望將RefCounted<Control> RefCounted<Button>RefCounted<Button>同時保持兩個對象引用計數,即僅當兩個實例都被處置以處置基礎對象時。

最好的方法是您是否可以編寫(就像C ++人們可以做到的那樣)

public RefCounted(RefCounted<U> other)
{
    ...whatever...
}

但是C#不允許這樣做。 因此解決方案是使用一些間接方式。

private readonly Func<T> valueProvider;
private readonly Action disposer;

private RefCounted(Func<T> value_provider, Action disposer)
{
    this.valueProvider = value_provider;
    this.disposer = disposer;
}

public RefCounted(T value) : this(() => value, value.Dispose)
{
}

public RefCounted<U> Cast<U>() where U : T 
{
    AddRef();
    return new RefCounted<U>(() => (U)(valueProvider()),this.Dispose);
}

public void Dispose(){
    if(InterlockedDecrement(ref refCount)<=0)
        disposer();
}

如果您的類具有任何屬於通用類型的字段,則別無選擇,只能將所有這些類型放入類中。 但是,如果您只是想從構造函數中隱藏某種類型,則需要使用上述技巧-使用隱藏的構造函數將所有內容放在一起,並定義一個普通的泛型函數來調用該構造函數。

暫無
暫無

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

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