Why does C# allow constructing an object from an interface in "new Shell32.Shell()"?

447 views Asked by At

I know that in C# in general you can't create an instance of an abstract class or an interface. Can someone help me understand this code (it compile without any errors).

Shell32.Shell shObj = new Shell32.Shell();

Shell32.Shell is an interface from 'shell32.dll'

I tried the following, but it did NOT compile:

[CoClass(typeof(ShellClass))]
[Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")]
public interface OtherShell : Shell
{
}
OtherShell shObj = new OtherShell();

Update:

To make it work, I just needed to add the ComImport attribute and change the co-class (I can't choose Shell32.ShellClass).

Thanks guys!

2

There are 2 answers

4
user2864740 On BEST ANSWER

In addition to all the other information, here is the how it results in compiled code. The usage of the interface is merely a code nicety.

IL_000c: newobj       instance void [Interop.Shell32]Shell32.ShellClass::.ctor()

That is, it is a compile-time transformation from the interface "to" the class, based on the [CoClass] attribute.

Per, https://stackoverflow.com/a/1094140/2864740, which shows a minimal example case:

[In addition to CoClassAttribute, you] need both the ComImportAttribute and the GuidAttribute for it to work.

5
Tom John On

If you right click in Visual Studio on Shell32.Shell and go to definition you'll get the following definition of the interface:

using System.Runtime.InteropServices;

namespace Shell32
{
    [CoClass(typeof(ShellClass))]
    [Guid("286E6F1B-7113-4355-9562-96B7E9D64C54")]
    public interface Shell : IShellDispatch6
    {
    }
}

Do the same on the ShellClass and you'll get the concrete class that's being created in your code:

Shell32.Shell shObj = new Shell32.Shell();