WinRT Component structs with apparent properties and methods in C#

Gavin Williams 761 Reputation points
2020-06-29T01:37:38.39+00:00

Reading the documentation for Windows Runtime Components at ... https://learn.microsoft.com/en-us/windows/uwp/winrt-components/creating-windows-runtime-components-in-csharp-and-visual-basic I'm looking at the following paragraph...

In .NET, primitive types such as the Int32 structure have many useful properties and methods, such as the TryParse method. By contrast, primitive types and structures in the Windows Runtime only have fields. When you pass these types to managed code, they appear to be .NET types, and you can use the properties and methods of .NET types as you normally would.

This makes me wonder if it's possible for me to make a WinRT Component struct that appears to have properties and methods when using it from C#. What magic sauce is required to do this?

Universal Windows Platform (UWP)
{count} votes

1 answer

Sort by: Most helpful
  1. Gavin Williams 761 Reputation points
    2020-08-20T13:35:13.917+00:00

    I was looking at making a WinRT component library to wrap DirectX, and at first I looked at just wrapping SharpDX - I know that's a double wrapper - but it was an easy way for me to prototype the API and prove how it would work. I've never really done any interop scenario's beyond trivial experiments. So it seems like a reasonable way to approach it, the idea is more important than the performance right now.

    Because it was C#, it was actually pretty easy to get going, it's just C#, so I started working on DirectX enums, and then description structs and into the resource classes.

    TBH I can't exactly remember now what I was thinking when I asked this, I'm just looking back at the work I was doing at the time I asked. I suspect I was thinking ahead on how to make a component look like it's a proper C# component. And that would mean rich structs - with methods.

    I may have been thinking about the Color type. Look at SharpDX color type ...

    https://github.com/sharpdx/SharpDX/blob/master/Source/SharpDX.Mathematics/Color.cs

    It's an expressive struct with encapsulated functions.

    And consider the DX color type ...

    https://learn.microsoft.com/en-us/windows/win32/api/directxpackedvector/ns-directxpackedvector-xmcolor

    It's not as expressive as the SharpDX type, it has multiple constructors and overloads the = operator.

    I think it was a design choice by Alexandre Mutel, the author of SharpDX to employ rich types as that's what C# dev's expect, and the language has the capability. I know C++ can have rich structs, but I suppose DirectX was written 20 years ago in the C era, or was it COM that limited Direct X's expressiveness?

    I think it's a sensible approach for any replacement library to follow the SharpDX API style and employ rich types. If I look at the Color struct in WinRT...

    Color struct // see https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.color?view=netcore-3.1

    I see that it has methods, so Microsoft can write rich WinRT structs, but It looks like we can't. I guess that's the source of my question.

    However...

    Since then I have moved away from the idea of using WinRT Components for any kind of user-friendly library. It just seems too restrictive. I don't think it's really going to be easy to make an API that I'm satisfied with.

    My new way of thinking about WinRT components is - they may be good at interopping between C# & C++ (one day) but in terms of front facing libraries to be used in applications, I would be better off using a .Net Standard Library to define the API's and a second WinRT Component library for just the interop alone. To make that idea clear, I previously believed that the way to best use C++/WinRT was to wrap something like DX or other performance code in a WinRT Component and that's what would be used from C#, but now I think that's probably not right. Rather, the WinRT Component just wraps the C++ as tightly as possible in it's particular style. And then that should be in turn wrapped in a .Net Standard Library so that a C# app developer can use that instead. And the the library developer is free to make something that looks like C#.

    0 comments No comments