Repository: dotnet/maui
File: src/Controls/src/BindingSourceGen/ITypeSymbolExtensions.cs (C#)

Code before:
				}
			}
		}

		return false;
	}

	/// <summary>
	/// Checks if a property name could be generated by CommunityToolkit.Mvvm's [ObservableProperty] attribute,
	/// and returns the inferred property type if found.
	/// </summary>
	/// <param name="symbol">The type to search</param>
	/// <param name="propertyName">The name of the property to find</param>
	/// <param name="compilation">The compilation (can be null)</param>
	/// <param name="propertyType">The inferred property type if an ObservableProperty field is found</param>
	/// <returns>True if an ObservableProperty field was found that would generate this property</returns>
	public static bool TryGetObservablePropertyType(this ITypeSymbol symbol, string propertyName, Compilation? compilation, out ITypeSymbol? propertyType)
	{
		propertyType = null;

		if (compilation == null)
			return false;

		// ObservableProperty generates a PascalCase property from a camelCase or _camelCase field
		// Try common field naming patterns
		var possibleFieldNames = new[]
		{
			char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1), // name from Name
			"_" + char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1) // _name from Name
		};

		// Look for a field with one of the possible names - search in the type and base types
		foreach (var fieldName in possibleFieldNames)
		{
			var fields = GetAllFields(symbol, fieldName);

			foreach (var field in fields)
			{
				// Check if the field has the ObservableProperty attribute
				var hasObservableProperty = field.GetAttributes().Any(attr =>
					attr.AttributeClass?.Name == "ObservablePropertyAttribute" ||
					attr.AttributeClass?.ToDisplayString() == "CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute");

				if (hasObservableProperty)
				{
					propertyType = field.Type;
					return true;
				}
			}
		}


Review comment (suggestion):
The docs also mention a third possible case, even though it's likely not the common one:

> The name of the generated property will be created based on the field name. The generator assumes the field is named either lowerCamel, _lowerCamel or m_lowerCamel, and it will transform that to be UpperCamel to follow proper .NET naming conventions. The resulting property will always have public accessors, but the field can be declared with any visibility (private is recommended).

Let's add the `m_` prefix support, it is a trivial change.

Code after:
				}
			}
		}

		return false;
	}

	/// <summary>
	/// Checks if a property name could be generated by CommunityToolkit.Mvvm's [ObservableProperty] attribute,
	/// and returns the inferred property type if found.
	/// </summary>
	/// <param name="symbol">The type to search</param>
	/// <param name="propertyName">The name of the property to find</param>
	/// <param name="compilation">The compilation (can be null)</param>
	/// <param name="propertyType">The inferred property type if an ObservableProperty field is found</param>
	/// <returns>True if an ObservableProperty field was found that would generate this property</returns>
	public static bool TryGetObservablePropertyType(this ITypeSymbol symbol, string propertyName, Compilation? compilation, out ITypeSymbol? propertyType)
	{
		propertyType = null;

		if (compilation == null || string.IsNullOrEmpty(propertyName))
			return false;

		// ObservableProperty generates a PascalCase property from a camelCase, _camelCase, or m_camelCase field
		// Try common field naming patterns
		var possibleFieldNames = new[]
		{
			char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1), // name from Name
			"_" + char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1), // _name from Name
			"m_" + char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1) // m_name from Name
		};

		// Look for a field with one of the possible names - search in the type and base types
		foreach (var fieldName in possibleFieldNames)
		{
			var fields = GetAllFields(symbol, fieldName);

			foreach (var field in fields)
			{
				// Check if the field has the ObservableProperty attribute
				var hasObservableProperty = field.GetAttributes().Any(attr =>
					attr.AttributeClass?.Name == "ObservablePropertyAttribute" ||
					attr.AttributeClass?.ToDisplayString() == "CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute");

				if (hasObservableProperty)
				{
					propertyType = field.Type;
					return true;
				}
			}
		}