非generics类中的generics构造函数是否受支持?

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

例:

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

generics只用于构造函数,没有依赖于它们的字段/属性,我使用它(generics)来强制执行f1和f2的types关联。

备注 :我find了解决方法 – 静态方法创build,但无论如何,我很好奇,为什么我有直接的方法的问题。

不,通用构造函数在generics或非generics类中都不受支持。 同样的事件,属性和终结器不支持。

只是偶尔我同意这将是方便的 – 但语法看起来很糟糕。 例如,假设你有:

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

什么会

 new Foo<string>() 

做? 调用非generics类的generics构造函数,或generics类的普通构造函数? 你不得不以某种方式区分它们,这将是凌乱的:(

同样,考虑generics类中的generics构造函数:

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

你将如何调用构造函数? 希望我们都可以同意:

 new Foo<string><int>() 

是相当丑陋的…

所以是的,在语义上它偶尔会有用 – 但不幸的是,由此产生的丑陋平衡。

generics构造函数不被支持,但你可以通过简单的定义一个返回一个新的Foo的genericsstatic方法来解决这个问题:

 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); 

这是一个关于如何使用额外的构造函数types参数的实例,以及解决方法。

我将为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>同时保留两个对象引用计数,即只有当两个实例都被放置来处理底层对象时。

最好的方法是如果你可以写(就像C ++人可以做的那样)

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

但是C#不允许这样做。 所以解决scheme是使用一些间接的。

 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(); } 

如果你的类有任何genericstypes的字段,你别无select,只能把这些types放到类中。 但是,如果只是想从构造函数中隐藏某个types,则需要使用上述技巧 – 使用隐藏的构造函数将所有内容放在一起,并定义一个普通函数来调用构造函数。