C#
VisualStudio
Unity
ReSharper
VisualStudio2017

【Visual Studio】Unityエンジニアから見たReSharperの便利機能まとめ

はじめに

本記事はVisual Studio Advent Calendar 2017の24日目の記事です。

昨日は tafuji さんのVisual Studio 拡張機能から Visual Studio プロジェクトを弄ってみるでした、お誕生日おめでとうございました!

ReSharper

  • 「このクラス、どの名前空間だっけ…?」
  • 「このループ処理、LINQで簡潔に書けそうだけどどのオペレータ使えば良いんだっけ…?」
  • 「このLINQ、もっと簡潔に書ける気がする」

上記のような場面は少なからずあると思います。
それらの悩みをすぐに解決してくれるVisual Studioの拡張プラグインがReSharperです。

resharper_logo_300x300.png

機能紹介

コーディング規約の統一

ss7.gif

ReSharper > Options... > Code Editing > C# > NamingStyleで命名規則を設定することが出来ます。

2017-12-25_02h46_24.png

リネーム

ss10.gif

使われていないコードの強調表示

2017-12-25_00h18_41.png

使われていないメソッドや変数、名前空間を灰色で表示してくれます。

欠落している名前空間のインポート

ss5.gif

ループ処理からLINQへの変換

ss3.gif

Before
private static void Hoge()
{
    // 1から100までの偶数の和を表示する
    IEnumerable<int> numbers = Enumerable.Range(1, 100);
    int sum = 0;

    foreach (int number in numbers)
    {
        if (number % 2 == 0)
        {
            sum += number;
        }
    }

    Debug.Log(sum);
}
After
private static void Hoge()
{
    // 1から100までの偶数の和を表示する
    IEnumerable<int> numbers = Enumerable.Range(1, 100);
    int sum = numbers.Where(number => number % 2 == 0).Sum();

    Debug.Log(sum);
}

LINQの簡略化

ss4.gif

Before
private static void Hoge()
{
    // 1から100までの整数に101が含まれていないか?
    IEnumerable<int> numbers = Enumerable.Range(1, 100);

    if (!numbers.Any(number => number == 101))
    {
        Debug.Log("101は含まれていない");
    }
}
After
private static void Hoge()
{
    // 1から100までの整数に101が含まれていないか?
    IEnumerable<int> numbers = Enumerable.Range(1, 100);

    if (numbers.All(number => number != 101))
    {
        Debug.Log("101は含まれていない");
    }
}

オブジェクト初期化子の提案

ss2.gif

Before
public class HogeClass
{
    public int Age;
    public string Name;
}

private static void Hoge()
{
    var hogeClass = new HogeClass();
    hogeClass.Age = 0;
    hogeClass.Name = "Hoge";

    Debug.Log(hogeClass.Name);
}
After
public class HogeClass
{
    public int Age;
    public string Name;
}

private static void Hoge()
{
    var hogeClass = new HogeClass
    {
        Age = 0,
        Name = "Hoge"
    };

    Debug.Log(hogeClass.Name);
}

コレクション初期化子の提案

ss1.gif

Before
private static void Hoge()
{
    var list = new List<string>();
    list.Add("Hoge");
    list.Add("Piyo");
    list.Add("HogePiyo");

    Debug.Log(list.First());
}
After
private static void Hoge()
{
    var list = new List<string> {"Hoge", "Piyo", "HogePiyo"};

    Debug.Log(list.First());
}

Postfix Templates

ss6.gif

Postfix Templatesを使うことで流れるようにコーディングすることが出来ます。

ショートカット
.arg Method(expr)
.await await expr
.cast ((SomeType) expr)
.else if (!expr)
.field _field = expr;
.for for (var i = 0; i < xs.Length; i++)
.foreach foreach (var x in expr)
.forr for (var i = xs.Length-1; i >= 0; i--)
.if if (expr)
.lock lock (expr)
.new new SomeType()
.not !expr
.notnull if (expr != null)
.null if (expr == null)
.par (expr)
.parse int.Parse(expr)
.prop Property = expr;
.return return expr;
.sel l selected + expression l
.switch switch (expr)
.throw throw expr;
.to lvalue = expr;
.trypars int.TryParse(expr, out value)
.typeof typeof(TExpr)
.using using (expr)
.var var x = expr;
.while while (expr)
.yield yield return expr;

C# 6.0相当のコードへの変換

ss8.gif

Before
[SerializeField]
private int _hoge;
public int Hoge { get { return _hoge; } }
After
[SerializeField]
private int _hoge;
public int Hoge => _hoge;

ラムダ式本体によるプロパティの記述や文字列補間を提案してくれます。

ss9.gif

Before
private void Hoge()
{
    // ※ nameof演算子もC# 6.0相当の機能
    Debug.Log(string.Format("{0}: {1}", nameof(_hoge), _hoge));
}
After
private void Hoge()
{
    Debug.Log($"{nameof(_hoge)}: {_hoge}");
}

参考記事

ReSharper 2017.3 Help
ReSharperのすすめ
ReSharperのテンプレート機能について

おわりに

ReSharperは快適なコーディング環境を作り上げる素晴しいVisual Studioの拡張プラグインです。

本記事に含まれていないオススメ機能がありましたらお気軽に編集リクエストやコメントを送っていただけますと追記いたします。

明日のVisual Studio Advent Calendar 2017baba_s さんの【Visual Studio 2017】オススメの拡張機能 その2(25個)です!