Is it possible to define valid C# interface that cannot be implemented? [closed]

此生再无相见时 提交于 2019-12-31 10:46:14

问题


I'm thinking about this (meta) question for couple of days already:
Is it possible to define valid C# interface, that cannot be implemented in any way?

Possible variations of this question: Is it possible to define such interface in C# 2.0, 3.0, 4.0, 5.0? Is it possible to define such interface that would not even compile when implemented, or that would compile but throw runtime exception?

Edit: I know such interface will be useless just by definition, but is a nice answer for lectures or testing applicants for a programming job how good they know C#.


回答1:


Is it possible to define valid C# interface that cannot be implemented?

This trivia question is not a good fit for StackOverflow, but what the heck, it is easily answered. (Wrongly, as it turns out! Read on!)

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

IFoo<T> cannot be implemented for any T because there is no type argument that can be substituted for T. C doesn't work because C does not have a public parameterless constructor, and there can be no derived class of C because the default constructor is private. (Well, there could be an accessible derived class of C inside C, but there isn't in this case.)


UPDATE: Commenter "mike z" correctly points out that

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

implements the interface, though of course now there is no way to instantiate X<T>!

Even better, user "GranBurguesa" points out that a derived class of C is permitted to be declared, just so long as it never calls the private constructor; this is only possible if it crashes and dies on instantiation. (Well, to be picky, it would also be permitted for the recursive calls to be optimized down to an infinite loop instead of a crash.)

Both devious workarounds pose a philosophical question: if an interface is implemented by a class no one can instantiate, is it really implemented? Of course GranBurguesa demonstrates that IFoo<D> can be implemented and constructed, so my answer is actually wrong.


There are also cases, such as the one hinted at in SLaks' deleted answer, in which an abuse of the generic mechanism leads to an "infinitary" type. Such types are not legal in the CLR; the C# design team has considered adding similar language to the C# compiler spec but hasn't gotten around to it yet. Use of these types can crash the compiler or the runtime.

For an example of an infinitary type that crashes the compiler, see my article:

To Infinity But Not Beyond


Here's one. Cut n paste this code into Visual Studio and you'll see that this interface cannot be implemented:

interface ΙAmAPerfectlyOrdinaryInterface { }

class C : IAmAPerfectlyOrdinaryInterface { }




回答2:


As long as we're talking trivia, I think this is a valid implementation of Eric Lippert's attempt:

class Program
{
    static void Main(string[] args)
    {
        D test = new D();
    }
}

class C
{
    private C() { }
}

interface IFoo<T> where T : C, new() { }

class D : C
{
    public D()
        : this(5) { }

    public D(int x)
        : this() { }
}

class Dfoo : IFoo<D> { }

It compiles fine but crashes with a StackOverflowException when you instantiate D.




回答3:


If you're trying to factor out an old interface you could mark the interface with the ObsoleteAttribute attribute.

Edit: as @Magnus noted in the comments, if you set the Error attribute to true it's usage will cause an error.




回答4:


If a type is accessible and unsealed, it will be possible for outside code to create instances of that type and there isn't really anything the base type can do about it. No "full trust" or Reflection required.

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);
    }
}

Note that if code is written only in C#, a base-class destructor might squawk if it notices that the object isn't of a legitimate type, but code written in languages other than C# would allow the override of Finalize to exit without chaining to its parent.

I think it's possible to specify an open generic interface with a combination of struct and class constraints which no combination of types could possibly fulfill, e.g.

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

I'm not sure whether such an open-generic type would really qualify as an "interface", though, or whether only closed generic types can really qualify as interfaces (or classes, or structs).



来源:https://stackoverflow.com/questions/16779479/is-it-possible-to-define-valid-c-sharp-interface-that-cannot-be-implemented

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!