Pattern matching issues inside converters of UI Toolkit

Sorry for the long read - it is just full of examples.

Trying to use converters in UI Toolkit according to this link. So, it seems like some converters doesn’t pass, and no visible feedback for this.

Say, I have a data source - my custom type with a property of type object (I am using it for boxing values, but it is not important for this topic). In this type I add the binding to a label and a converter like this

protected void SetValueBinding(Label label, string propertyPath)
{
	DataBinding binding = new DataBinding()
	{
		dataSourcePath = new PropertyPath(propertyPath),
		bindingMode = BindingMode.ToTarget,
	};

	binding.sourceToUiConverters.AddConverter((ref object val) =>
        {
            var res = val switch
            {
                double doubleValue => doubleValue.ToString("0.#", new CultureInfo("en-us")),
                string => val,
                _ => throw new NotImplementedException(),
            };
            return res;
        });
		
	label.dataSource = this;
	label.SetBinding(nameof(label.text), binding);
}

The code of converter isn’t performed - no entry into its code under debug. And of course it doesn’t convert the incoming values.

But if I change only the single line from this

string => val,

to this

string stringValue => stringValue,

all works fine.

So, I tried various combinations, and here is what I have found:

these combinations work:

double doubleValue => doubleValue.ToString("0.#", new CultureInfo("en-us")),
string stringValue => stringValue,
double doubleValue => ((double)val).ToString("0.#", new CultureInfo("en-us")),
string stringValue => stringValue,
double => ((double)val).ToString("0.#", new CultureInfo("en-us")),
string stringValue => stringValue,

these don’t

double doubleValue => doubleValue.ToString("0.#", new CultureInfo("en-us")),
string => val,
double doubleValue => ((double)val).ToString("0.#", new CultureInfo("en-us")),
string => val,
double => ((double)val).ToString("0.#", new CultureInfo("en-us")),
string => val,

It looks like Unity supports type pattern matching, declaration pattern matching, and mixed type plus declaration patterns matching. But why variants with the second type pattern matching (for string) don’t work? But it works if I use it as a declaration.

More interesting - if I put any of the “not working variants” into the same scope of SetValueBinding method, but outside of the binding declaration, they work fine! For example, I’ll copy the code from the start of this topic and add the using of Unity’s TypeConverter at the end, then just run this code under debug to check the variable “result”

protected void SetValueBinding(Label label, string propertyPath)
{
	DataBinding binding = new DataBinding()
	{
		dataSourcePath = new PropertyPath(propertyPath),
		bindingMode = BindingMode.ToTarget,
	};

	binding.sourceToUiConverters.AddConverter((ref object val) =>
        {
            var res = val switch
            {
                double doubleValue => doubleValue.ToString("0.#", new CultureInfo("en-us")),
                string => val,
                _ => throw new NotImplementedException(),
            };
            return res;
        });
		
	label.dataSource = this;
	label.SetBinding(nameof(label.text), binding);
	
	
	// ------------- here starts the additional code
	object obj = 1.2345;

	TypeConverter<object, object> myConverter = (ref object val) =>
	{
		var res = val switch
		{
			double => ((double)val).ToString("0.#", new CultureInfo("en-us")),
			string => val,
			_ => throw new NotImplementedException(),
		};

		return res;
	};

	// it is always "1.2" as it should be -
	// no matter which of the six variants of pattern matching I use here
	var result = myConverter(ref obj); 
}