かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Caller Info試してみた

Windows 8 CPとVS11 betaを入れてみたので試してみました。試してみたといっても下記サイトのコードをそのままコピペして動かしてみた感じです。
http://ufcpp.net/study/csharp/ap_ver5.html#CallerInfo

コードの全体はこんな感じ。

using System;
using System.Runtime.CompilerServices;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Trace.WriteLine("OK");
        }
    }

    public static class Trace
    {
        public static void WriteLine(string message,
            [CallerFilePath] string file = "",
            [CallerLineNumber] int line = 0,
            [CallerMemberName] string member = "")
        {
            var s = string.Format("{0}:{1} - {2}: {3}", file, line, member, message);
            Console.WriteLine(s);
        }
    }
}

これを動かすとこんな結果になります。ファイル名、行番号、呼び出しメンバーの名前がばっちりとれてます。

c:\Users\****\Documents\Visual Studio 11\Projects\ConsoleApplication1\ConsoleApp
lication1\Program.cs:10 - Main: OK

とりあえず使い道

こんな使い道があるかな。

ログ用APIのおともに

今回の例のようにログを出力するAPIにとてもぴったりです。

プロパティ名が必用なメソッドの実装に

たとえばINotifyPropertyChangedなんかの実相で今まで文字列や式木でプロパティ名を渡してた部分が以下のようにすっきりなります。

public class Sample : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
        var h = this.PropertyChanged;
        if (h != null)
        {
            h(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private string name;
    public string Name
    {
        get { return this.name; }
        set
        {
            this.name = value;
            // 自分でプロパティ名を指定しなくてもいい!!
            this.RaisePropertyChanged();
        }
    }
}

ばっちり動きました。下記のようなコードを実行すると

var s = new Sample();
s.PropertyChanged += (_, e) => Console.WriteLine(e.PropertyName + " changed");
s.Name = "a";
s.Name = "b";

こんな結果になります。

Name changed
Name changed

素敵!