Visual Studio 2019新功能 - 2

by vivid 18. 三月 2020 11:48

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N200321702
出刊日期: 2020/3/18

本篇文章延續《Visual Studio 2019新功能 - 1》一文的內容,介紹號稱地表最強開發工具Visual Studio 2019問市後,所帶來的一些好用的新功能,讓你應用在日常開發之中。

程式碼重構(Refactor)功能

程式碼重構(Refactor)並不是新功能,不過Visual Studio 2019加強了這部分,新增多種修訂程式碼的能力,讓你設計更精簡、高品質的程式碼。

同步命名空間與資料夾名稱

在C#專案之中,資料夾名稱通常會是命名空間(namespace)的一部分,在專案中新增類別時,預設會根據資料夾的位置來決定類別所在的命名空間。因此,若將類別程式檔案移動到專案中的其它資料夾,常常會有命名空間與資料夾名稱不一致的問題,容易導致程式設計師的混淆,我們可以利用程式碼重構(Refactor)功能來修訂這個問題。例如以下圖片中的程式碼,包含一個「Emplyee」類別,位於「JSONApp1」命名空間下,若將此類別檔案搬到「Models」資料夾,你可以透過程式碼重構,選取「Emplyee」類別所在的命名空間,按滑鼠右鍵,從快捷選單之中,選取「將命名空間變更為’ JSONApp1.Models ’」項目來同步命名空間與資料夾名稱,請參考下圖所示:

clip_image002

圖 1:同步命名空間與資料夾名稱。

或者選取快捷選單之中的「將內容移到命名空間」項目,手動再輸入新的命名空間名稱,來進行同步的動作,請參考下圖所示:

clip_image004

圖 2:「移到命名空間」。

匿名型別轉換成元組

程式碼重構(Refactor)功能現在可以將匿名型別(Anonymous Type)轉換成元組(Tuple)。例如底下程式碼在LINQ運算式中使用到了匿名型別「new { Name = s , s.Length }」:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      var names = new string[] { "apple" , "amy" , "cindy" };
      var query = from s in names
                  select new { Name = s , s.Length };

      foreach ( var item in query ) {
        Console.WriteLine( item );
      }
    }
  }
}


 

你可以選取「new { Name = s , s.Length }」這段程式碼,直接按下「CTRL」 + 「.」組合鍵,隨即便會出現一個「轉換為元組」的快速修訂選項,以及預覽變更視窗,請參考下圖所示:

clip_image006

圖 3:「轉換為元組」選項。

點選「轉換為元組」選項項目之後,便自動將上例程式碼修訂如下,查詢的結果將會是元組組成的列舉(IEnumerable<(string Name, int Length)>):

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      var names = new string[] { "apple" , "amy" , "cindy" };
      var query = from s in names
                  select (Name: s, s.Length);

      foreach ( var item in query ) {
        Console.WriteLine( item );
      }
    }
  }
}

 

「for」迴圈轉換成LINQ語法

程式碼重構也增加一個新選項可以將「for」迴圈轉換成LINQ語法,或Lamdba運算式(Lambda expression)。舉例來說,以下主控台應用程式的程式碼包含一個靜態的「GetList」方法,可以將陣列中的字串,某個字元開頭的字串篩選出來:

using System;
using System.Collections.Generic;

namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      foreach ( var item in GetList( "L" ) ) {
        Console.WriteLine( item );
      }
    }
    static IEnumerable<string> GetList( string key ) {
      string[] empList = new[] { "Mary" , "Candy" , "Lulu" , "Lisa" };

      foreach ( var item in empList ) {
        if ( item.StartsWith( key ) ) {
          yield return item;
        }
      }
    }
  }
}

 

範例中的「Main」方法叫用「GetList」方法時,傳入特定字元當篩選條件,這個範例程式的執行結果參考如下:

clip_image008

圖 4:篩選資料。

在Visual Studio 2019開發工具,選取程式碼編輯視窗中的「foreach」迴圈,按滑鼠右鍵,選取快捷選單中的「快速動作與重構」項目(或是按下「CTRL」+「.」組合鍵),請參考下圖所示:

clip_image010

圖 5:「快速動作與重構」。

接著就會出現一個清單,讓你選擇要轉換成LINQ運算式(LINQ Expression)語法,還是擴充方法(Extension Method)的呼叫語法,請參考下圖所示:

clip_image012

圖 6:「轉換至LINQ」。

若選擇「轉換至LINQ」選項,則將程式碼轉換成LINQ 運算式(LINQ Expression),上例的程式碼將會自動修訂如下:

using System;
using System.Collections.Generic;
using System.Linq;

namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      foreach ( var item in GetList( "L" ) ) {
        Console.WriteLine( item );
      }
    }
    static IEnumerable<string> GetList( string key ) {
      string[] empList = new[] { "Mary" , "Candy" , "Lulu" , "Lisa" };
      return from item in empList
             where item.StartsWith( key )
             select item;
    }
  }
}

 

若選擇快捷選單中的「轉換為LINQ (呼叫表單)」選項(這裏Visual Studio 2019中文版的翻譯有點怪,原文是 Convert to LINQ (call form)),則轉換成以下程式碼,將使用擴充方法(Extension Method)呼叫語法:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;

namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      foreach ( var item in GetList( "L" ) ) {
        Console.WriteLine( item );
      }
    }
    static IEnumerable<string> GetList( string key ) {
      string[] empList = new[] { "Mary" , "Candy" , "Lulu" , "Lisa" };
      return empList.Where( item => item.StartsWith( key ) ).Select( item => item );
    }
  }
}

 

提取成員到基底類型

C#支援物件導向,透過繼承來實現程式碼的重複使用性。程式碼重構現在也提供「提取成員到基底類型」功能,可以將子類別的程式碼,移動到父類別之中。舉例來說,參考以下範例程式碼,「MyCalc」類別繼承了「MyMath」類別,目前「MyCalc」類別之中包含了「Add」、「Substract」兩個方法:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      MyCalc c = new MyCalc();
      int r = c.Add( 1 , 2 );
      Console.WriteLine( r );
    }
  }
  class MyMath {

  }
  class MyCalc : MyMath {

    public int Add( int x , int y ) {
      return x + y;
    }
    public int Substract( int x , int y ) {
      return x - y;
    }
  }
}

 

若我們想將其中的「Add」方法的定義移動到父類別,只要選取「Add」方法的程式碼,按下「CTRL」+ 「.」組合鍵,利用程式碼重構來修正程式碼,若選取快捷選單中的「提取’Add’最多’MyMath’(Pull ‘Add’ up to ‘MyMath’)」項目,請參考下圖所示:

clip_image014

圖 7:選取「提取’Add’最多’MyMath’(Pull ‘Add’ up to ‘MyMath’)」。

便自動將上例程式碼轉換程式碼如下,「Add」方法的定義會移動到「MyMath」類別之中:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      MyCalc c = new MyCalc();
      int r = c.Add( 1 , 2 );
      Console.WriteLine( r );
    }
  }
  class MyMath {

    public int Add( int x , int y ) {
      return x + y;
    }

  }
  class MyCalc : MyMath {
    public int Substract( int x , int y ) {
      return x - y;
    }
  }
}

 

若選取快捷選單中的「將成員提取直到基底類型(Pull members up to base type)」選項,則會跳出一個「提升成員」視窗,讓你選擇要搬移的成員,請參考下圖所示:

clip_image016

圖 8:「將成員提取直到基底類型(Pull members up to base type)」選項。

若同時勾選上圖中的「Add」與「Substract」兩個方法,則自動轉換成以下程式碼,「Add」與「Substract」方法的定義都會移動到「MyMath」類別之中:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      MyCalc c = new MyCalc();
      int r = c.Add( 1 , 2 );
      Console.WriteLine( r );
    }
  }
  class MyMath {

    public int Add( int x , int y ) {
      return x + y;
    }
    public int Substract( int x , int y ) {
      return x - y;
    }

  }
  class MyCalc : MyMath {
  }
}

 

提取成員到介面

提取成員的功能也可以擴充到介面(Interface)。以底下程式碼為例,「MyCalc」類別實作了「IMyMath」介面,目前介面之中沒有定義任何成員:

 

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      MyCalc c = new MyCalc();
      int r = c.Add( 1 , 2 );
      Console.WriteLine( r );
    }
  }
  interface IMyMath {

  }
  class MyCalc : IMyMath {

    public int Add( int x , int y ) {
      return x + y;
    }
    public int Substract( int x , int y ) {
      return x + y;
    }
  }
}


選取快捷選單中的「快速動作與重構」項目(或是按下「CTRL」+「.」組合鍵),利用程式重構修正程式碼,請參考下圖所示:

clip_image018

圖 9:「提取’Add’最多’IMyMath’(Pull ‘Add’ up to ‘IMyMath’)」。

若選取快捷選單中的「提取’Add’最多’IMyMath’(Pull ‘Add’ up to ‘IMyMath’)」項目(這邊的中文還是很怪啊),便自動將上例程式碼轉換如下,「IMyMath」介面中,將定義一個「Add」方法:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using System.Linq;
namespace JSONApp1 {

  class Program {
    static void Main( string[] args ) {
      MyCalc c = new MyCalc();
      int r = c.Add( 1 , 2 );
      Console.WriteLine( r );
    }
  }
  interface IMyMath {
    int Add( int x , int y );
  }
  class MyCalc : IMyMath {

    public int Add( int x , int y ) {
      return x + y;
    }
    public int Substract( int x , int y ) {
      return x + y;
    }
  }
}

 

一次匯入多個命名空間

Visual Studio之前的版本有個功能,可以透過Quick Fix功能來加入using語法,以匯入某個型別所在的命名空間,請參考下圖所示:

clip_image020

圖 10:匯入某個型別所在的命名空間。

現在這個功能又大幅增強了,若在程式碼編輯視窗之中一次貼入一大段程式碼,Quick Fix功能會跳出一個「新增遺漏的Using(Add missing usings)」選項,讓你一次匯入多個命名空間,請參考下圖所示:

clip_image022

圖 11:「新增遺漏的Using(Add missing usings)」選項。

方法參數換行與取消換行

類別中的方法(Method)若有定義多個參數,有時不易閱讀,你可以利用程式重構功能,將每個參數的定義換行呈現,並進行縮排動作,以改善這個問題,請參考下圖所示:

clip_image024

圖 12:方法參數換行。

反過來,已換行的參數,也可以利用「將所有參數取消換行」功能還原成未換行之前的樣子,請參考下圖所示:

clip_image026

圖 13:「將所有參數取消換行」選項。

此外沒有使用到的參數,其名稱以灰色顯示,透過程式碼重構,也可以自動將未使用到的參數移除,請參考下圖所示:

clip_image028

圖 14:「移除未使用的參數」選項。

Tags:

.NET Magazine國際中文電子雜誌 | Visual Studio | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List