[GH-ISSUE #135] Structs confuse their members #81

Open
opened 2026-05-05 11:03:51 -06:00 by gitea-mirror · 3 comments
Owner

Originally created by @vadi2 on GitHub (May 17, 2019).
Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/135

If I have the following as a struct:

   public struct Issue
    {
      private string _severity;
      [NotifySignal]
      public string Severity
      {
        get =>_severity;
        set => this.SetProperty(ref _severity, value);
      }

      private string _text;
      [NotifySignal]
      public string Text
      {
        get => _text;
        set => this.SetProperty(ref _text, value);
      }

      private string _location;
      [NotifySignal]
      public string Location
      {
        get => _location;
        set => this.SetProperty(ref _location, value);
      }
    }

Then the interop to QML will... confuse what member stores what. For example the following debug output:

C# code:

Console.WriteLine($"severity: {test.Severity}, text: {test.Text}, location: {test.Location}");

QML code:

console.log(`severity: ${issue.severity}, text: ${issue.text}, location: ${issue.location}`)

Will have this strange result:

C#:
severity: Error, text: Instance failed constraint sdf-20 "No slicing on the root element", location: StructureDefinition.differential[0]

QML:
severity: , text: Error, location: Instance failed constraint sdf-20 "No slicing on the root element"

Changing the struct to be a class magically fixed everything.

Originally created by @vadi2 on GitHub (May 17, 2019). Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/135 If I have the following as a struct: ```csharp public struct Issue { private string _severity; [NotifySignal] public string Severity { get =>_severity; set => this.SetProperty(ref _severity, value); } private string _text; [NotifySignal] public string Text { get => _text; set => this.SetProperty(ref _text, value); } private string _location; [NotifySignal] public string Location { get => _location; set => this.SetProperty(ref _location, value); } } ``` Then the interop to QML will... confuse what member stores what. For example the following debug output: C# code: ```charp Console.WriteLine($"severity: {test.Severity}, text: {test.Text}, location: {test.Location}"); ``` QML code: ```js console.log(`severity: ${issue.severity}, text: ${issue.text}, location: ${issue.location}`) ``` Will have this strange result: C#: severity: Error, text: Instance failed constraint sdf-20 "No slicing on the root element", location: StructureDefinition.differential[0] QML: severity: , text: Error, location: Instance failed constraint sdf-20 "No slicing on the root element" Changing the struct to be a class magically fixed everything.
gitea-mirror added the
help wanted
label 2026-05-05 11:03:51 -06:00
Author
Owner

@pauldotknopf commented on GitHub (Jun 10, 2019):

This does indeed appear to be an issue with Qml.Net. I will look into it.

However, I strongly suggest not having mutable structs. If you need mutability, just make it a class.

<!-- gh-comment-id:500269240 --> @pauldotknopf commented on GitHub (Jun 10, 2019): This does indeed appear to be an issue with Qml.Net. I will look into it. However, I strongly suggest not having mutable structs. If you need mutability, just make it a class.
Author
Owner

@pauldotknopf commented on GitHub (Jun 10, 2019):

I tried to resolve the problem, couldn't work it out.

I've added a failing test if someone else wants to take a stab at it.

See commit c8fac8f

<!-- gh-comment-id:500284600 --> @pauldotknopf commented on GitHub (Jun 10, 2019): I tried to resolve the problem, couldn't work it out. I've added a failing test if someone else wants to take a stab at it. See commit c8fac8f
Author
Owner

@pauldotknopf commented on GitHub (Jun 10, 2019):

I use SharpLab to inspect IL.

using System;
using System.Threading.Tasks;
public class C {
    public void M() {
        
    }
    
    public static void LoadValue(NetVariant result, String value)
    {
    }
    
    public static void Test(NetReference param1, NetVariantList param2, NetVariant param3, ref Task param4)
    {
        var tempValue = ((TestClass)param1.Instance).Method();
        LoadValue(param3, tempValue);
    }
    
    public class NetVariantList
    {
    }
    
    public class NetVariant
    {
    }
    
    public class NetReference
    {
        public object Instance { get; set; }
    }
    
    public struct TestClass
    {
        public string Method()
        {
            return "";
        }
    }
}
<!-- gh-comment-id:500285996 --> @pauldotknopf commented on GitHub (Jun 10, 2019): I use [SharpLab](https://sharplab.io) to inspect IL. ```csharp using System; using System.Threading.Tasks; public class C { public void M() { } public static void LoadValue(NetVariant result, String value) { } public static void Test(NetReference param1, NetVariantList param2, NetVariant param3, ref Task param4) { var tempValue = ((TestClass)param1.Instance).Method(); LoadValue(param3, tempValue); } public class NetVariantList { } public class NetVariant { } public class NetReference { public object Instance { get; set; } } public struct TestClass { public string Method() { return ""; } } } ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/qmlnet#81
No description provided.