C# 非泛型类中是否支持泛型构造函数?

C# 非泛型类中是否支持泛型构造函数?,c#,generics,constructor,C#,Generics,Constructor,不支持吗,支持吗,但我必须做一些技巧 例如: class Foo { public Foo<T1,T2>(Func<T1,T2> f1,Func<T2,T1> f2) { ... } } 泛型只在构造函数中使用,没有依赖于它们的字段/属性,我使用它来强制f1和f2的类型关联 备注:我发现了解决方法-静态方法Create,但无论如何,我很好奇为什么我对直接方法有问题。不,泛型或非泛型类都不支持泛型构造函数。同样,不支持泛型事件、属性和终结

不支持吗,支持吗,但我必须做一些技巧

例如:

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>()
太可怕了


是的,从语义上来说,它偶尔会有用——但不幸的是,由此产生的丑陋抵消了这一点。

不支持泛型构造函数,但您可以通过简单地定义一个返回新Foo的泛型静态方法来解决这一问题:

它是这样使用的:

// 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包装器:

这似乎很好。但您迟早会希望将RefCounted强制转换为RefCounted,同时保持两个对象引用计数,即仅当两个实例都被释放以释放基础对象时

最好的方法是如果你能像C++一样写人可以做< /P>
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();
}

如果您的类有任何泛型类型的字段,那么您别无选择,只能将所有这些类型放入该类。但是,如果您只是想对构造函数隐藏某些类型,则需要使用上述技巧-使用隐藏的构造函数将所有内容组合在一起,并定义一个普通的泛型函数来调用该构造函数。

如果不允许泛型类和非泛型类使用相同的名称,就可以解决相同的命名类问题。C允许吗?。对于泛型类的泛型构造函数,我不认为它太可怕——它只是更高阶的泛型。一句话——泛型类中的构造函数是泛型的,因为类是泛型的。但是,对于您的答案,它不能指定额外的泛型参数。谢谢你提供了非常好的例子@彼得:不,samed命名类问题不是问题,因为尽管可以通过类型arity重载类,但没有歧义。请参阅Tuple的例子。@ Maias:我不认为构造函数是泛型的,正是因为它没有引入任何额外的类型参数。您是否认为List.RexOf是一种泛型方法,仅仅因为它是泛型类型?实际上,类名重载是有用的,因为您把非泛型类放在所有静态方法中。在C++中,我总是有这样的奇数对MyClass和MyCasePrime.在C中,可以有几个元组类和调用Tuple.Create5,hello,4.5是干净的。
public RefCounted(RefCounted<U> other)
{
    ...whatever...
}
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();
}