rksoftware

Visual Studio とか C# とかが好きです

Visual Studio でソースファイルを並べて表示する

多分以前にも書いていると思いますが、せっかくなので書いておきます。
前回の記事の画像をとるために使った Visual Studio の機能です。なんとソースファイルと横に並べて表示できます!

■ 手順

ソースファイルを複数開きます。すると普通にタブ表示になります。
f:id:rksoftware:20210921000834j:plain

一方のファイルのタブをドラッグします。5つの四角が表示されます。
f:id:rksoftware:20210921000851j:plain

5つの四角の左のものにドロップします。
f:id:rksoftware:20210921000910j:plain

見事、ファイル並んで表示されました!
f:id:rksoftware:20210921000924j:plain

global using

これまで暗黙的な global using 関連の記事を何個か書いてきましたが、実は global using は書いていませんでした。

■ global using

どこかの1ファイルで using だけですべてのファイルで using したことになる機能です。

■ 前提条件

今回のコードを試すには .NET 6 環境と 暗黙的な global using の無効化が必要です。

■ 例

次のコードは Class2 のファイルでは System 名前空間が using されていないのでエラーになります。

f:id:rksoftware:20210920235403j:plain

using System;

namespace TestApp
{
    internal class Class1
    {
        void Method()
            => Console.WriteLine("");
    }
}

namespace TestApp
{
    internal class Class2
    {
        void Method()
            => Console.WriteLine("");
    }
}

エラーメッセージ

英語版

Error    CS0103  The name 'Console' does not exist in the current context

日本語版

エラー    CS0103  現在のコンテキストに 'Console' という名前は存在しません

■ global using

Class1usingglobal というキーワードをつけてます。

f:id:rksoftware:20210920235420j:plain

global using System;

namespace TestApp
{
    internal class Class1
    {
        void Method()
            => Console.WriteLine("");
    }
}

namespace TestApp
{
    internal class Class2
    {
        void Method()
            => Console.WriteLine("");
    }
}

エラーがなくなりました!
便利に使えば使えそうですが、プロジェクト内のほかのソースコードファイルに影響を及ぼす非常に強い機能です。不用意に使うと場合によっては別のファイルのソースコードを壊しかねない点は注意して活用してください。

Visual Studio 2022 Preview 4 の注目新機能 sync namespaces

Visual Studio 2022 Preview 4 のリリースノートはこちら↓

■ C# の特徴

C# はソースファイルのフォルダ構造と名前空間を一致させなくてよいという特徴があります。

しかしこの特徴、意図して活用している方は少ないのではないでしょうか? 活用していない場合、この特徴は意図しない名前空間の設定を行っていてもエラーになってくれないという課題を生みます。

■ sync namespaces

sync namespaces というこの素敵機能は名前空間をフォルダ構造に合わせてくれる画期的便利機能です。

ここに、Folder1 というフォルダの中に Folder2 という名前空間のファイルがあります。

f:id:rksoftware:20210919232436j:plain

namespace TestApp.Folder2
{
    internal class Class1
    {
    }
}

ソリューション エクスプローラーで右クリックでコンテキストメニューを表示し sync namespaces を選択します。

f:id:rksoftware:20210919232518j:plain

整いました!

f:id:rksoftware:20210919232545j:plain

namespace TestApp.Folder1
{
    internal class Class1
    {
    }
}

素晴らしい。

■ 補足

この素敵機能ですが、プロジェクトの階層でした使えないようです。フォルダのコンテキストメニューでは残念ながら出てきません。

f:id:rksoftware:20210919232629j:plain

Visual Studio 2019 の 16.11.3 がリリースされました

Visual Studio のアップデート 16.11.3 がリリースされました。

最近は機械翻訳でもい感じに翻訳されるのですが見ていきましょう。

■ 更新内容

問題の解決

  • Xamarin.iOS プロジェクトでデバッグのターゲットに "Remote Device" が出てこない問題。
  • スタートメニューからショートカット リンクが消える問題。
  • ビルドエラーが非常に多いと Visual Studio は応答しなくなる問題。
  • 起動時にライブユニットテストがクラッシュする問題 (OutOfMemoryException)
  • 32 ビットをターゲットにした WinForms のデザイナ上でマウスの (ホイールを?) スクロールするとデザイナがクラッシュし、Visual Studio も落ちる問題。

セキュリティ

セキュリティに関する問題の解決が 1 件あります。
誰もが踏むというものではないですが、全員なるべく最速でアップデートしましょう。

機能追加

今回は機能追加はないようです。

なるべく早くアップデート

今回は嵌ると厳しい問題が解消しています。嵌る前に素早くアップデートしておきましょう。

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。

暗黙的な global using ディレクティブをもっと細かく制御する

先日暗黙的な global using ディレクティブについて書きました。

実は暗黙的な global using ディレクティブは .csproj ファイルでもっと細かく制御できます。

■ Import Remove / Import Include

上に貼ったリンクの通りですが、例えば次のような要素を .csproj に書き足すことで制御できます。

<ItemGroup>
  <Import Remove="System" />
  <Import Include="Test" />
</ItemGroup>

ここでは System 名前空間を外して、Test 名前空間を追加しています。
全体の .csproj ファイルは次のようになっています。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <Import Remove="System" />
    <Import Include="Test" />
  </ItemGroup>

</Project>

■ 設定語のイメージ

この設定を行ったソースコードのイメージです。

f:id:rksoftware:20210915005221j:plain

Test.Console クラスは Test 名前空間が using されているので使えています。System 名前空間が using されていないので競合もしていません。
一方 String クラスはエラーです。System 名前区間が using されていないのでクラスが見つかりません。

■ 備えよう

使いこなせば強力な機能です。しっかり覚えて .NET 6 / C# 10 に備えましょう。

暗黙的な global using ディレクティブによる破壊的変更の回避

先日暗黙的な global using ディレクティブによる破壊的変更について書きました。

記事の中で実際に .NET 5 で通っていたコードが .NET 6 でエラーになるパターンを挙げて確認しました。

■ DisableImplicitNamespaceImports プロパティ

このエラーは、 .csproj ファイルで DisableImplicitNamespaceImports プロパティを設定すると回避できます(暗黙的な global using を無効化できます)。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>
  </PropertyGroup>

</Project>

ドキュメントによると ImplicitUsings プロパティというのもあるそうですが、設定しても効果が見られませんでした。要調査。

f:id:rksoftware:20210912232609j:plain

DisableImplicitNamespaceImports プロパティを設定したコードです。
以前エラーになっていた Console はエラーになっていません。代わりに String (System.String クラス) がエラーになっています。
using System; がないため。

DisableImplicitNamespaceImports プロパティ。覚えておきましょう。

暗黙的な global using ディレクティブによる破壊的変更

暗黙的な global using ディレクティブについては次を参照してください、

■ System 名前空間に注目して検証

次のコードは .NET 5 ではまったく問題なくビルドできるコードです。
3 行目の ConsoleTest 名前空間のクラスとして認識されています。

using Test;

Console.WriteLine("");

namespace Test
{
    static class Console
    {
        public static void WriteLine(string value) {; }
    }
}

これを .NET 6 にしてしまうと...

参考 - .NET 6 への変更方法

エラーになります。 f:id:rksoftware:20210912024225j:plain

Error    CS0104  'Console' is an ambiguous reference between 'Test.Console' and 'System.Console'

日本語だと

エラー    CS0104  'Console' は、'Test.Console' と 'System.Console' 間のあいまいな参照です

暗黙で using System; がついてしまうので、分からなくなってしまっていますね。

そうそう踏まないと思いますが、油断しているとレガシーコードを扱っている際に踏むかもしれません。備えましょう。