tixture55’s diary

主にプログラミング関係の日記です。

C#の書き方(LINQ、クラスの継承の禁止、outキーワード)

※この記事はC#初学者による初学者用の記事です。

 

C#を使うと、PHPに比べ、制限をかけるような書き方ができるのが特徴です。またソート処理と一口に言っても、ラムダ式を使うソート、LINQを使ったソート、Comparisonデリゲートを使ったソートなどいろいろ方法があります。
 個人的には、方法が多い分、どのようにクラスやメソッドを指定するか、どんなソート方法を使うかなど柔軟に書いていく必要があるのかなぁと思ったりします。

 

LINQを使ったソート

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

namespace Sample
{
  class Sample
  {
     static void Main()
     {
        int src = {3, 1, 5, 4, 2};

        // LINQでソート
        var dst = src.OrderBy(a => -a);

        Console.WriteLine("[{0}]", string.Join(", ", dst));
        Console.ReadKey();
     }
  }
}

{5,4,3,2,1}が結果として出力されます。これは一次元配列ですから、あんまり恩恵的にはぱっとしないですが、二次元配列になっても極端にコード量を増やすことなく、ソート処理を書くことができます。

 

 

using System;
using System.Linq;

namespace Sample
{
  class Sample
  {
     static void Main()
     {
        //ジャグ配列
        var jag = new {
          new {0, 1, 200},
          new
{1, 3, 100},
          new {2, 4, 100},
          new
{3, 2, 300},
          new [] {4, 0, 200},
        };

        var sorted = jag.OrderBy(e => e[1]); //昇順(index=1)

        foreach (var s in sorted) {
           foreach (var e in s) {
              Console.Write(e + ", ");
           }
           Console.WriteLine();
        }
     }
  }
}


感覚的にはすごくすっきりした感じです。LINQいいですね。(速度的にはArray.Sort()より遅めだけど、配列の要素数が何十、何百じゃなければ無視してよさげ)

 

クラスの継承を禁止する

 
 
sealed class Asealed class A
{
  public virtual void VirtualMethod() { } //エラー
  protected void ProtectedMethod() { } //警告
}

上記のclass Aは親クラスとなることはできません。 上記のclass Aは親クラスとなることはできません。 基本的にクラスは拡張できる余地を残すべきで、むやみにシールクラスにする必要はありません。 ソフトウェアの再利用性の観点からも多用すべきではありませんが、継承したくないときには使えるキーワードです。

 outパラメータ付き引数での変数宣言

 outパラメータを使用するには、メソッド定義と呼び出し元のメソッドの両方でoutパラメータを使用するには、メソッド定義と呼び出し元のメソッドの両方で outキーワードを明示的に使用する必要があります。outキーワードを使うと呼び出されたメソッドで 引数の値を変更することができます。(inキーワードのパラメータは不可)

 
class Point { 
  public int X { get; }
      public int Y { get; private set; }
      public void GetCoordinates(out int x, out int y)
      {   
            x = X;    y = Y; 
      }
}

■C#6.0でのメソッド呼び出し方は↓

 
 
void OldStyle(Point p)
    int x, y; //事前に変数を宣言する必要があった 
    p.GetCoordinates(out x, out y);
      WriteLine($"({x}, {y})");
}

C#7.0では下記のように宣言できるようになった。

void PrintCoordinates(Point p)
{
  WriteLine(x1); // 変数のスコープ内であっても宣言前には参照するとコンパイルエラー
  p.GetCoordinates(out var x1, out int y1);
  WriteLine($"(x1,y1)=({x1}, {y1})"); // 変数のスコープはメソッド呼び出しと同じスコープ内
}

 

参考サイト 

www.sejuku.net

www.buildinsider.net