首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将接口用作C#泛型类型约束?

如何将接口用作C#泛型类型约束?
EN

Stack Overflow用户
提问于 2009-07-08 07:18:02
回答 8查看 132.2K关注 0票数 184

有没有办法获得下面的函数声明?

代码语言:javascript
复制
public bool Foo<T>() where T : interface;

即。其中T是接口类型(类似于where T : classstruct)。

目前,我已经满足于:

代码语言:javascript
复制
public bool Foo<T>() where T : IBase;

其中IBase被定义为一个空接口,它由我的所有自定义接口继承...不是很理想,但应该能行得通。为什么不能定义泛型类型必须是接口呢?

不管它有什么价值,我之所以要这样做,是因为Foo在需要接口类型的地方进行反射……我可以将其作为一个普通参数传入,并在函数本身中进行必要的检查,但这似乎更加安全(而且我认为性能更好,因为所有检查都是在编译时完成的)。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-07-08 07:22:18

你能做的最接近的(除了你的基接口方法)是"where T : class",意思是引用类型。没有语法来表示“任何接口”。

例如,在WCF中使用此("where T : class")将客户端限制为服务契约(接口)。

票数 146
EN

Stack Overflow用户

发布于 2011-05-03 19:13:03

我知道这有点晚了,但是对于那些感兴趣的人,你可以使用运行时检查。

代码语言:javascript
复制
typeof(T).IsInterface
票数 120
EN

Stack Overflow用户

发布于 2012-02-07 01:48:45

为了跟进Robert的回答,这甚至更晚了,但您可以使用静态帮助器类对每个类型只进行一次运行时检查:

代码语言:javascript
复制
public bool Foo<T>() where T : class
{
    FooHelper<T>.Foo();
}

private static class FooHelper<TInterface> where TInterface : class
{
    static FooHelper()
    {
        if (!typeof(TInterface).IsInterface)
            throw // ... some exception
    }
    public static void Foo() { /*...*/ }
}

我还注意到,你的“应该工作”的解决方案实际上并不工作。考虑一下:

代码语言:javascript
复制
public bool Foo<T>() where T : IBase;
public interface IBase { }
public interface IActual : IBase { string S { get; } }
public class Actual : IActual { public string S { get; set; } }

现在没有什么可以阻止你这样调用Foo了:

代码语言:javascript
复制
Foo<Actual>();

毕竟,Actual类满足IBase约束。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1096568

复制
相关文章

相似问题

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