tmds / Tmds.DBus

D-Bus for .NET
MIT License
282 stars 54 forks source link

Incorrectly generated names for properties inside of classes attributed with `Dictionary` when returned from `GetAll` #299

Closed Rune580 closed 3 months ago

Rune580 commented 3 months ago

When a class is attributed with Dictionary the properties get incorrectly generated names when GetAll is called, for example

[Dictionary]
public class MediaPlayer2Properties
{
    public bool CanQuit = false;
    public bool Fullscreen = false;
    public bool CanSetFullscreen = false;
    public bool CanRaise = false;
    public bool HasTrackList = false;
    public string Identity = "MusicDrone";
    public string DesktopEntry = "";
    public string[] SupportedUriSchemes = [];
    public string[] SupportedMimeTypes = [];
}
public class MediaPlayerObject : IMediaPlayer2, IPlayer
{
    // ...

    private MediaPlayer2Properties _mediaPlayer2Properties;

    // ...

    Task<MediaPlayer2Properties> IMediaPlayer2.GetAllAsync()
    {
        return Task.FromResult(_mediaPlayer2Properties);
    }
}

Each field gets a generated name like '<CanQuit>k__BackingField': <false>. the full dump of the return is as follow Screenshot_20240804_133026

Removing the Dictionary attribute, and modifying the GetAll method to return IDictionary<string, object> instead provides the correct names.

public class MediaPlayer2Properties
{
    public bool CanQuit = false;
    public bool Fullscreen = false;
    public bool CanSetFullscreen = false;
    public bool CanRaise = false;
    public bool HasTrackList = false;
    public string Identity = "MusicDrone";
    public string DesktopEntry = "";
    public string[] SupportedUriSchemes = [];
    public string[] SupportedMimeTypes = [];
}
public class MediaPlayerObject : IMediaPlayer2, IPlayer
{
    // ...

    private MediaPlayer2Properties _mediaPlayer2Properties;

    // ...

    Task<IDictionary<string, object>> IMediaPlayer2.GetAllAsync()
    {
        return Task.FromResult<IDictionary<string, object>>((Dictionary<string, object>)_mediaPlayer2Properties);
    }
}

Screenshot_20240804_133151

I assume this wasn't ever caught before due to the sort of niche use case. But the workaround is required in order to be in spec for org.mpris.MediaPlayer2, I was struggling to get my service recognized without the workaround.

tmds commented 3 months ago

Each field gets a generated name like 'k__BackingField': .

I'm not sure where these backing fields come from.

Could it be that you had the members in MediaPlayer2Properties declared as properties instead of fields?

Rune580 commented 3 months ago

well this is embarrassing, this seems to be entirely my own fault. closing. sorry about that :/