C#学习教程:是否可以定义无法实现的有效C#接口?分享


是否可以定义无法实现的有效C#接口?

我已经考虑了这个(meta)问题几天了:
是否有可能定义有效的C#接口,无法以任何方式实现?

这个问题的可能变化:是否可以在C#2.0,3.0,4.0,5.0中定义这样的接口? 是否有可能定义在实现时甚至不编译的接口,或者可以编译但抛出运行时exception的接口?

编辑 :我知道这样的界面只是按照定义无用,但对于编程工作的演讲或测试申请人来说,他们对C#的了解有多好,这是一个很好的答案。

是否可以定义无法实现的有效C#接口?

这个琐事问题不适合StackOverflow,但是很简单,很容易回答。 (错误的是,事实certificate!继续阅读!)

class C { private C() {} } interface IFoo where T : C, new() { } 

IFoo不能为任何T实现,因为没有可以替换T类型参数。 C不起作用,因为C没有公共无参数构造函数,并且不能有C派生类,因为默认构造函数是私有的。 (好吧, C里面可能有一个可访问的派生类C ,但在这种情况下不存在。)


更新:评论者“迈克z”正确地指出了这一点

 class X : IFoo where T : C, new() {} 

实现接口,虽然当然现在没有办法实例化X

更好的是,用户“GranBurguesa”指出允许声明派生类C,只要它从不调用私有构造函数; 这只有在实例化时崩溃并死亡时才有可能。 (好吧,为了挑剔,也可以将递归调用优化到无限循环而不是崩溃。)

两种狡猾的变通方法都提出了一个哲学问题:如果一个接口是由一个没有人可以实例化的类实现的,那么它是否真的实现了? 当然GranBurguesacertificate了IFoo可以实现和构建,所以我的答案实际上是错误的。


还有一些案例,例如在SLaks删除的答案中暗示的案例,其中滥用通用机制导致“无限”类型。 这些类型在CLR中是不合法的; C#设计团队已经考虑过将类似的语言添加到C#编译器规范中,但尚未解决它。 使用这些类型可能会使编译器或运行时崩溃。

有关崩溃编译器的infinitary类型的示例,请参阅我的文章:

无限但不是超越


这是一个。 剪切n将此代码粘贴到Visual Studio中,您将看到无法实现此接口:

interface ΙAmAPerfectlyOrdinaryInterface { }

class C : IAmAPerfectlyOrdinaryInterface { }

只要我们谈论琐事,我认为这是Eric Lippert尝试的有效实现:

 class Program { static void Main(string[] args) { D test = new D(); } } class C { private C() { } } interface IFoo where T : C, new() { } class D : C { public D() : this(5) { } public D(int x) : this() { } } class Dfoo : IFoo { } 

它实例化D时编译很好但崩溃与StackOverflowException

如果您尝试分解旧接口,可以使用ObsoleteAttribute属性标记接口。

编辑:正如@Magnus在评论中指出的那样,如果将Error属性设置为true则其使用将导致错误。

如果一个类型是可访问和未密封的,那么外部代码可以创建该类型的实例,并且基本类型无法对其进行任何操作。 不需要“完全信任”或反思。

 public class CantDeriveMe { private CantDeriveMe() { } public override string ToString() { return "My type is " + this.GetType().ToString(); } } public class OhYeah : CantDeriveMe { static OhYeah CapturedInstance; ~OhYeah() { CapturedInstance = this; } OhYeah() : this(1/String.Empty.Length) { } OhYeah(int blah) : this() { } public static OhYeah Create() { try { new OhYeah(4); } catch (DivideByZeroException) { GC.Collect(); GC.WaitForPendingFinalizers(); } return CapturedInstance; } public static void test() { OhYeah it; it = OhYeah.Create(); Console.WriteLine("Result was ({0})", it); } } 

请注意,如果代码仅在C#中编写,则基类析构函数可能会发出声音,如果它注意到该对象不是合法类型,但使用C#以外的语言编写的代码将允许覆盖Finalize而不链接到它的父母。

我认为可以指定一个开放的通用接口,它结合了struct和class约束,没有类型的组合可能实现,例如

 public interface evil where T : struct,U where U : class 

我不确定这样的开放generics类型是否真的有资格作为“接口”,或者只是封闭的generics类型是否真的可以作为接口(或类或结构)。

上述就是C#学习教程:是否可以定义无法实现的有效C#接口?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/ckf/1301106.html

(0)
上一篇 2023年1月8日 上午8:50
下一篇 2023年1月8日 上午11:24

精彩推荐