1

I found the following compiler-generated code using DotPeek analyzing one of .NET assemblies:

[UnsafeValueType, NativeCppClass]
[StructLayout(LayoutKind.Sequential, Size = 16)]
internal struct DWriteTextAnalysisNode<MS::Internal::Text::TextInterface::Native::IDWriteNumberSubstitution *>
{
}

I am wondering what it means? How to rewrite this in C#? Especially this part:

<MS::Internal::Text::TextInterface::Native::IDWriteNumberSubstitution *>
Qué Padre
  • 2,005
  • 3
  • 24
  • 39
  • IDWriteNumberSubstitution us a COM interface. The rest of the name sounds like just an artificial qualifier – Marc Gravell Dec 24 '13 at 08:19
  • 1
    This code is already in c# – Kirill Bestemyanov Dec 24 '13 at 08:20
  • What does angle brackets and star sign mean here? – Qué Padre Dec 24 '13 at 08:22
  • @KirillBestemyanov How could I write and compile similar using mocks? – Qué Padre Dec 24 '13 at 08:26
  • You cannot mock it (it is COM, and it is unsafe). To mock you should write wrapper class and mock wrapper – Kirill Bestemyanov Dec 24 '13 at 08:28
  • The star denotes a pointer, and angle brackets typically surround type parameters. You might want to read up on both concepts before you get in too much further. You're about a quarter of a step away from all the C++ stuff that C# tries to protect you from. – cHao Dec 24 '13 at 08:29
  • @cHao Why would someone like to have struct SomeStruct? Why not SomeStruct? – Qué Padre Dec 24 '13 at 08:33
  • 1
    @QuéPadre: C++ templates aren't quite the same as C# generics. Because using different parameters can radically change the interpretation of the template, C++ basically has to create a new class for each combination of template name and type parameters it sees used. – cHao Dec 24 '13 at 08:49
  • @cHao Exactly! Now i got it! .NET makes a slob out of me =) – Qué Padre Dec 24 '13 at 09:02
  • @cHao Still didn't get something... Why would someone need to define C++ struct in C# code? – Qué Padre Dec 24 '13 at 09:09
  • 1
    @QuéPadre: Because it's not C# code. You're not seeing the code as they wrote it; you're seeing it as DotPeek's C#-scented decompiler interpreted it. – cHao Dec 24 '13 at 09:20

1 Answers1

7

You found this back in PresentationCore.dll. You are looking at code that was written in C++/CLI, not C#. It is one of the three major Microsoft .NET languages, beyond C# and VB.NET. Definitely the ugly step daughter, C++/CLI reason for being is its unparalleled ability to interop with native code written in C or C++.

Which gets lots of use in PresentationCore, System.Data as well, it contains heavy native code interop to take advantage of existing Microsoft apis. In this case it is DirectWrite, a text rendering api. It is a pretty complex native api that's well beyond the ability of standard pinvoke to interop with. C++/CLI supports using the native COM-style interfaces directly.

One aspect of C++/CLI is that the native C++ interfaces and classes can bleed into the assembly metadata. It is a bit of a flaw, it doesn't have a great way to suppress visibility of the native types. Only the opposite, making them visible with #pragma make_public. The C++/CLI compiler must generate a metadata definition for the type that's compatible with assembly metadata. Since these are native types under the hood, the closest reasonable match is a value type. It is entirely opaque, you don't see the members of the type. Just a blob, pretty similar to fixed size buffer types in C#.

So this is just an artifact. There's no sensible way to do the same thing in C#, nor is there a reason to.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536