{"record":{"id":"fec7de7d027483dd","repo":"unoplatform/uno","slug":"the-default-lookuppositionalparameters-implementat","errorCode":null,"errorMessage":"The default LookupPositionalParameters implementation does not allow duplicate arity of markup extensions","messagePattern":"The default LookupPositionalParameters implementation does not allow duplicate arity of markup extensions","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/SourceGenerators/System.Xaml/System.Xaml/XamlType.cs","lineNumber":725,"sourceCode":"\t\t\tif (UnderlyingType == null/* || !IsMarkupExtension*/) // see nunit tests...\n\t\t\t\treturn null;\n\n\t\t\t// check if there is applicable ConstructorArgumentAttribute.\n\t\t\t// If there is, then return its type.\n\t\t\tif (parameterCount == 1) {\n\t\t\t\tforeach (var xm in GetAllMembers ()) {\n\t\t\t\t\tvar ca = xm.GetCustomAttributeProvider ().GetCustomAttribute<ConstructorArgumentAttribute> (false);\n\t\t\t\t\tif (ca != null)\n\t\t\t\t\t\treturn new XamlType [] {xm.Type};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar methods = (from m in UnderlyingType.GetConstructors (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) where m.GetParameters ().Length == parameterCount select m).ToArray ();\n\t\t\tif (methods.Length == 1)\n\t\t\t\treturn (from p in methods [0].GetParameters () select SchemaContext.GetXamlType (p.ParameterType)).ToArray ();\n\n\t\t\tif (SchemaContext.SupportMarkupExtensionsWithDuplicateArity)\n\t\t\t\tthrow new NotSupportedException (\"The default LookupPositionalParameters implementation does not allow duplicate arity of markup extensions\");\n\t\t\treturn null;\n\t\t}\n\n\t\tBindingFlags flags_get_static = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;\n\n\t\tprotected virtual EventHandler<XamlSetMarkupExtensionEventArgs> LookupSetMarkupExtensionHandler ()\n\t\t{\n\t\t\tvar a = this.GetCustomAttribute<XamlSetMarkupExtensionAttribute> ();\n\t\t\tif (a == null)\n\t\t\t\treturn null;\n\t\t\tvar mi = type.GetMethod (a.XamlSetMarkupExtensionHandler, flags_get_static);\n\t\t\tif (mi == null)\n\t\t\t\tthrow new ArgumentException (\"Binding to XamlSetMarkupExtensionHandler failed\");\n\t\t\treturn (EventHandler<XamlSetMarkupExtensionEventArgs>) Delegate.CreateDelegate (typeof (EventHandler<XamlSetMarkupExtensionEventArgs>), mi);\n\t\t}\n\n\t\tprotected virtual EventHandler<XamlSetTypeConverterEventArgs> LookupSetTypeConverterHandler ()\n\t\t{","sourceCodeStart":707,"sourceCodeEnd":743,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/SourceGenerators/System.Xaml/System.Xaml/XamlType.cs#L707-L743","documentation":"LookupPositionalParameters throws NotSupportedException when a MarkupExtension type has more than one public constructor with the same parameter count (duplicate arity) AND the schema context does not opt into supporting that. Positional markup-extension parameters in XAML (e.g. {Binding path}) map to a specific constructor; if two constructors are ambiguous for a given arity, the default resolver cannot pick one and refuses rather than guess. SupportMarkupExtensionsWithDuplicateArity being false gates whether this throws.","triggerScenarios":"Defining a MarkupExtension subclass with two constructors taking the same number of arguments, then using it with positional arguments in XAML. The resolver finds methods.Length != 1 for the requested parameterCount, and because SupportMarkupExtensionsWithDuplicateArity is false, it throws.","commonSituations":"Authoring a custom MarkupExtension with overloaded constructors of equal arity; porting WPF markup extensions that rely on a particular overload-resolution rule; third-party extensions that add convenience constructors colliding in arity.","solutions":["Disambiguate the constructors on the MarkupExtension so each distinct arity has exactly one constructor (remove or rename a colliding overload).","Use named property assignment syntax in XAML ({MyExt Prop=value}) instead of positional arguments, which bypasses positional constructor resolution.","If duplicate arity is intentional, set XamlSchemaContextSettings.SupportMarkupExtensionsWithDuplicateArity = true when constructing the XamlSchemaContext (note: the framework then returns null instead of throwing, pushing resolution elsewhere)."],"exampleFix":"// before (MarkupExtension with duplicate arity)\npublic class MyExt : MarkupExtension {\n    public MyExt(string s) {}\n    public MyExt(int i) {}\n}\n// XAML: <Binding Source=\"{x:Static ...}\" /> ambiguous\n\n// after\npublic class MyExt : MarkupExtension {\n    public MyExt(string s) {}\n    public string IntValue { get; set; }\n}\n// XAML: {local:MyExt someText, IntValue=5}","handlingStrategy":"validation","validationCode":"// Ensure markup extension has a unique constructor arity:\nvar arities = typeof(MyExt).GetConstructors().GroupBy(c => c.GetParameters().Length)\n    .Where(g => g.Count() > 1).ToArray();\nif (arities.Length > 0) throw new InvalidOperationException(\"Duplicate constructor arity on MyExt\");","typeGuard":null,"tryCatchPattern":"try { var parms = xamlType.GetPositionalParameters(count); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"duplicate arity\")) {\n    // fall back to named-property syntax or report a config error\n}","preventionTips":["Design custom MarkupExtensions with one constructor per arity.","Default to named-argument XAML syntax for extensions that need flexibility.","Add a unit test asserting unique constructor arities on shipped markup extensions."],"tags":["xaml","markup-extension","reflection","positional-parameters"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}