かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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

素敵!