繁体   English   中英

使用约束泛型类型的静态方法C#

[英]using static methods of a constrained generic type C#

我有一个通用类:

public class Foo<T> where T: Interface
{

}

T被强制实现的接口有2个静态方法。

在构造函数中,我希望能够基本上执行以下操作:

public Foo()
{
   value1 = T.staticmethod1();
   value2 = T.staticmethod2();
}

使用我上面发布的伪代码无法实现这一点。 是不是可以用这种方式调用这些静态方法?

您可以使用扩展方法。 这种技术被命名为伪混合 虽然扩展方法实际上是静态的,但它们“假装”为实例方法,因此您仍然需要T的具体实例。

此外,如果您希望您的界面保留其作为自我记录“合同”的角色,这是一种作弊,它指定了您的T类应具有的方法。 但是它们是类型安全的(如果你没有在范围内引入IBarExtensions,你的Foo类将无法编译)

//our interface
public interface IBar {}

// the two static methods are define as extension methods
public static class IBarExtensions {
    public static string someMethod1(this IBar self) {
        return "my initialization 1";
    }
    public static string someMethod2(this IBar self) {
        return "my initialization 2";
    }
}

public class Foo<T> where T : IBar, new()
{
    public string value1 {get; private set;}
    public string value2 {get; private set;}

    public Foo() {
        T t = new T(); // we can do this because of the "new()" constraint
                           // in the class definition
                           // Alternatively we could pass an instance of T in
                           // the constructor 
                           // public Foo(T t)
        value1 = t.someMethod1();
        value2 = t.someMethod2();       
    }
}

测试

public class TestBar : IBar {}
void Main()
{
    var c = new TestBar();

    var t = new Foo<TestBar>();
    Console.WriteLine(t.value1);
}

不,这是不可能的。 甚至没有dynamic 通用的约束(如接口),但仅适用于实例成员。 您可以考虑将这些方法作为Func<T> / Action<T>委托传递给(参数)吗?

除此之外,你唯一的(也是不受欢迎的)选择就是反思。 或者更好:重新思考我们的方法。

C#不允许您调用接口中定义的静态方法。 它发出一个命名不佳的错误消息:

如果您使用以允许接口中的静态成员的语言编写的库,并且您尝试从C#访问静态成员,也会发生CS0017。

如果C#允许它,你将使用接口名称而不是通用参数名称来调用它们:

// doesn't work:
public Foo() {
  value1 = Interface.staticmethod1();
  value2 = Interface.staticmethod2(); 
} 

所以,你有几个选择:

  1. 使用允许调用这些成员的语言(我认为 VB.NET和C ++ / CLI允许这样做)。 您可以编写一个可以在C#中使用的小适配垫片;
  2. 询问为您提供此界面的人(可能甚至是您)在界面中不使用静态成员。 它们可以移动到单独的静态类。 该类甚至可以嵌套在接口中(如果语言允许),它将在C#中工作。

不可能使用约束泛型类型参数的静态成员,因为特定类型中静态成员的存在不会说明派生类型是否具有具有该名称的兼容成员。 假设类型“Foo”具有返回Int32的静态函数Wowzo(),类型DerivedFoo1具有不同的静态函数Wowzo(),它还返回Int32,类型DerivedFoo2(源自Foo),具有静态成员Wowzo()返回一个String,类型DerivedFoo3有一个名为Wowzo的嵌套类。 如果T是一个被限制为Foo后代的类型参数,那么T.Wowzo是什么?

您还可以使用非静态方法作为调用静态方法的包装器。 然后,非静态方法可以成为您的界面的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM