【问题标题】:Separate code file in Blazor gives bogus warning messagesBlazor 中的单独代码文件提供虚假警告消息
【发布时间】:2020-08-09 03:46:00
【问题描述】:

我有一个服务器端 Blazor 应用程序。在 Blazor 下编写剃须刀页面时有两种选择:将设计代码和 C# 代码放在一个“.razor”文件中,并将设计和代码文件分开为“.razor”和“.razor.cs”文件。问题是 Visual Studio 不完全支持剃须刀页面中的智能感知,但您始终可以将代码放在单独的文件中并使用完整的智能感知支持。这是一个包含代码块的最小示例剃须刀页面:

@page "/minimalsample"
<h3>MinimalSample</h3>

<MatChip Raised="true" @onclick="@OpenUp" @ref="SampleMenuButton" Label="Actions" LeadingIcon="cloud_download"></MatChip>

<MatMenu @ref="SampleMenu">
    <MatList SingleSelection="false" TwoLine="false">
        <MatListItem OnClick="@Format_Clicked" Style="height: auto">
            Format C: Drive
        </MatListItem>
        <MatListItem OnClick="@Shred_Clicked" Style="height: auto">
            Shred files
        </MatListItem>
    </MatList>
</MatMenu>

<br />

@ActionText

@code {

    private BaseMatMenu SampleMenu;
    private BaseMatChip SampleMenuButton;
    private string ActionText;

    private void OpenUp()
    {
        SampleMenu.OpenAsync(SampleMenuButton.Ref);
    }
    private void Format_Clicked()
    {
        ActionText = "Formatting C: Drive...";
    }
    private void Shred_Clicked()
    {
        ActionText = "Shredding user files...";
    }

}

此代码工作正常。当我单击按钮时它会打开一个菜单,并且菜单项也可以正常工作。我决定将代码和设计文件分开,以便能够使用 Visual Studio (2019) 的智能感知功能,现在我收到警告说:

警告 CS0649 字段“MinimalSample.SampleMenu”从未分配给, 并且将始终具有其默认值 null

“.razor”页面如下:

@page "/minimalsample"
@namespace Pages
<h3>MinimalSample</h3>

<MatChip Raised="true" @onclick="@OpenUp" @ref="SampleMenuButton" Label="Actions" LeadingIcon="cloud_download"></MatChip>

<MatMenu @ref="SampleMenu">
    <MatList SingleSelection="false" TwoLine="false">
        <MatListItem OnClick="@Format_Clicked" Style="height: auto">
            Format C: Drive
        </MatListItem>
        <MatListItem OnClick="@Shred_Clicked" Style="height: auto">
            Shred files
        </MatListItem>
    </MatList>
</MatMenu>

<br />

@ActionText

而代码文件“.razor.cs”为:

using MatBlazor;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Pages
{
    public partial class MinimalSample : ComponentBase
    {
        private BaseMatMenu SampleMenu;
        private BaseMatChip SampleMenuButton;
        private string ActionText;

        private void OpenUp()
        {
            SampleMenu.OpenAsync(SampleMenuButton.Ref);
        }
        private void Format_Clicked()
        {
            ActionText = "Formatting C: Drive...";
        }
        private void Shred_Clicked()
        {
            ActionText = "Shredding user files...";
        }

    }
}

我不得不更改按钮和菜单引用以具有一些默认值(只是为了让编译器满意!)。

    private BaseMatMenu SampleMenu = new BaseMatMenu();
    private BaseMatChip SampleMenuButton = new BaseMatChip();
    private string ActionText = "";

我知道这不是必需的,它在没有 new 运算符的情况下也能正常工作。然而编译器仍然抱怨变量“ActionText”被赋值但它的值从未被使用过。

我想以适当的方式消除警告(将代码移动到 .razor 页面不是这里的选项)。我能做些什么来摆脱这些警告?有没有可能这是一个编译器错误?

更新:

@NikProtsman 提供了一个可行的解决方案。我刚刚删除了 partial 修饰符,并将“.razor.cs”中的类定义名称从

public partial class MinimalSample : ComponentBase

public class MinimalSampleBase : ComponentBase

我还将 private 修饰符更改为 protected

...
...
    public class MinimalSampleBase : ComponentBase
    {
        protected BaseMatMenu SampleMenu;
        protected BaseMatChip SampleMenuButton;
        protected string ActionText;

        protected void OpenUp()
        {
            SampleMenu.OpenAsync(SampleMenuButton.Ref);
        }
        protected void Format_Clicked()
        {
            ActionText = "Formatting C: Drive...";
        }
        protected void Shred_Clicked()
        {
            ActionText = "Shredding user files...";
        }
    }
...
...

后来我把“.razor”页面改成了这样

@page "/minimalsample"
@namespace Pages
// added this line
@inherits MinimalSampleBase
...
...

现在我没有收到警告,我的代码正在按预期运行。

【问题讨论】:

    标签: c# visual-studio blazor matblazor


    【解决方案1】:

    文档显示使用部分类方法,但我总是使用继承模型来获得更好的运气。对于您的 .razor.cs 文件,您可以尝试将类称为基类:public class MinimalSampleBase : ComponentBase,然后在您的 .razor 文件中添加 @inherits MinimalSampleBase。您需要在标记页面上使用的所有private 字段和方法现在应该改为protected,但支持字段和支持方法仍应标记为私有。基类现在变成了一个“视图模型”,并且仍然获得完整的 VS Intellisense 和重构支持,并且您可以获得代码隐藏方法的所有好处,并且希望在您的情况下,它会使那些编译器警告消失。

    我还发现 Partial Class 方法会在我需要实现接口的任何地方引起问题,例如设置对服务的事件订阅和使用 IDisposable 取消订阅拆卸。然而,继承模型完美地工作。

    试一试并报告,我认为这会有所帮助,但我很想确定。

    【讨论】:

    • 感谢您的回答。看起来它应该是这样工作的。如果有人需要这个解决方案,我会发布最新的源代码。
    【解决方案2】:

    看起来我们需要等待 .NET 5:“这似乎是我们如何在预构建步骤中生成 Blazor 文件的骨架的问题,因为该预构建步骤会删除所有 Razor 内容,而不是在@functions / @code 中。从技术上讲,这将由源生成器修复,但这些在 .NET 5 中处于临界状态。”

    https://github.com/dotnet/aspnetcore/issues/20137

    编辑:我确认问题已在 .NET 5 中解决。它可以在没有继承/受保护属性等的情况下工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多