Visual Studio 2022中Blazor组件Tuple回调参数的IDE错误问题
问题描述
我有一个名为TagComponent的Blazor组件,接收4个参数,问题出在OnTagSelected回调参数上。代码可正常编译运行,但Visual Studio的错误列表和编辑器中显示红色波浪线错误。我的环境是Windows 10、Visual Studio Community 2022 Preview 17.4.0 Preview 2.0、.NET 6;在VSCode(使用.NET 6.0.401)中无此错误。
我需要通过@onclick事件从TagComponent向页面返回两个值,因此在EventCallback的TValue中使用了值元组。点击组件时,会根据元组中的布尔值在两个标签列表间切换标签。
页面代码片段
// other code omitted for brevity <p>Tags</p> <div class="tags-container"> @foreach (var tag in _allTags) { <TagComponent Name="@tag.Name" Id="@tag.Id" AddToProductList="true" OnTagSelected="TagSelected" /> } </div> // other code omitted for brevity
TagComponent.razor代码
<span class="tag-body" @onclick="SelectTag" > @Name </span> @code { [Parameter, EditorRequired] public string Name { get; set; } = default!; [Parameter, EditorRequired] public int Id { get; set; } [Parameter] public bool AddToProductList { get; set; } = false; [Parameter, EditorRequired] public EventCallback<(int id, bool addToProduct)> OnTagSelected { get; set; } private async Task SelectTag() { await OnTagSelected.InvokeAsync((Id, AddToProductList)); } }
页面中的TagSelected方法
@code { List<Tag> _allTags = new List<Tag>(); List<Tag> _productTags = new List<Tag>(); // other code omitted for brevity private void TagSelected((int id, bool addToProduct) selectedTag) { if (selectedTag.addToProduct) { var transferTag = _allTags.First(t => t.Id == selectedTag.id); _productTags.Add(new Tag(transferTag.Id, transferTag.Name)); _allTags.Remove(transferTag); } else { var transferTag = _productTags.First(t => t.Id == selectedTag.id); _allTags.Add(new Tag(transferTag.Id, transferTag.Name)); _productTags.Remove(transferTag); } } // other code omitted for brevity }
原因与解决方法
原因
这是Visual Studio 2022 Preview 17.4 Preview 2.0的编辑器分析器bug:Blazor的Razor编辑器对值元组作为EventCallback泛型参数的类型推断支持不完善,导致误报错误,实际代码逻辑和编译运行完全正常。
解决方法
方案1:升级Visual Studio版本
微软在后续的预览版及正式版中修复了这个值元组类型推断的问题,直接升级到17.4正式版或更高版本即可消除错误提示。
方案2:用自定义类/结构体替代值元组
定义一个专门的类型封装传递的参数,避免使用值元组:
// 项目共享类文件中添加 public class TagSelectionArgs { public int Id { get; set; } public bool AddToProduct { get; set; } }
修改TagComponent的EventCallback定义:
[Parameter, EditorRequired] public EventCallback<TagSelectionArgs> OnTagSelected { get; set; } private async Task SelectTag() { await OnTagSelected.InvokeAsync(new TagSelectionArgs { Id = Id, AddToProduct = AddToProductList }); }
同步修改页面的TagSelected方法参数:
private void TagSelected(TagSelectionArgs selectedTag) { if (selectedTag.AddToProduct) { var transferTag = _allTags.First(t => t.Id == selectedTag.Id); _productTags.Add(new Tag(transferTag.Id, transferTag.Name)); _allTags.Remove(transferTag); } else { var transferTag = _productTags.First(t => t.Id == selectedTag.Id); _allTags.Add(new Tag(transferTag.Id, transferTag.Name)); _productTags.Remove(transferTag); } }
方案3:抑制误报错误
如果暂时不想升级或修改代码,可以直接屏蔽Visual Studio的误报:
- 右键点击编辑器中的红色波浪线错误
- 选择Suppress > In Suppression File或Suppress > In Source
- 编辑器会自动添加抑制属性或注释,消除该错误提示
内容的提问来源于stack exchange,提问作者Bernardo Soccal
相关产品推荐
相关产品推荐

