首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用受约束的泛型类型C#的静态方法

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

Stack Overflow用户
提问于 2011-08-09 02:12:53
回答 5查看 2.9K关注 0票数 7

我有一个泛型类:

代码语言:javascript
复制
public class Foo<T> where T: Interface
{

}

T被强制实现的接口内部定义了2个静态方法。

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

代码语言:javascript
复制
public Foo()
{
   value1 = T.staticmethod1();
   value2 = T.staticmethod2();
}

这不能用我在上面发布的伪代码来完成。难道不能以这种方式调用这些静态方法吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-09 02:34:28

您也许能够使用扩展方法。这项技术已被命名为pseudo-mixins。尽管扩展方法实际上是静态的,但它们“假装”是实例方法,因此您仍然需要T的一个具体实例。

此外,如果您希望您的接口保留其作为自文档化“契约”的角色,以指定您的T类应该具有哪些方法,那么这也是一种欺骗。然而,它们是类型安全的(如果你不把IBarExtensions引入作用域,你的Foo类将不会被编译)

代码语言:javascript
复制
//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();       
    }
}

测试

代码语言:javascript
复制
public class TestBar : IBar {}
void Main()
{
    var c = new TestBar();

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

Stack Overflow用户

发布于 2011-08-09 02:16:44

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

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

票数 4
EN

Stack Overflow用户

发布于 2011-08-09 02:20:07

C#不允许调用接口中定义的静态方法。它会发出一条poorly named错误消息:

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

CS0017。

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

代码语言:javascript
复制
// doesn't work:
public Foo() {
  value1 = Interface.staticmethod1();
  value2 = Interface.staticmethod2(); 
} 

因此,您有几个选择:

  1. 使用允许调用这些成员的语言(我认为VB.NET和C++/CLI允许这样做)。您可以编写一个可以在C#中使用的小型自适应填充程序;
  2. 要求为您提供此接口的人(甚至可能是您)不要在接口中使用静态成员。可以将它们移动到单独的静态类中。这个类甚至可以嵌套在接口中(如果语言允许的话),并且它将在C#中工作。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6986576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档