LoginSignup
19
19

More than 5 years have passed since last update.

.NET2.0 で拡張メソッド(などのモダン機能)を使う

Last updated at Posted at 2014-03-02

本エントリーには誤った内容が含まれています。代わりにC#の言語バージョンと.NET Frameworkバージョン | ++C++; // 未確認飛行 C ブログ を参照してください。


.NET2.0 の案件、私は今や携わることはほとんど無いのですが、時おり社内での悲鳴を耳にします。

.NET2.0 であっても糖衣構文系の機能であれば新しい Visual Studio やコンパイラを使用することで利用可能です。

  • 暗黙的に型指定されたローカル変数(var)
  • 自動実装プロパティ
  • ラムダ式
  • オブジェクト/コレクション初期化子

ところが、拡張メソッドについては私はこれまで .NET3.5 が必要だと思っていました。

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            "a".Fuga();
        }
    }


    public static class Hoge
    {
        public static void Fuga(this string a)
        {

        }
    }
}

ExtensionAttributeNotFound.png

拡張メソッドは、その定義箇所と利用箇所(呼び出し側)がアセンブリを跨ぐ場合もあるため、属性によるマークが必要になります。そのため、属性クラスが含まれない .NET2.0 では使うことができないと。

…そう思っていた時期が私にもありました。

どうやら、同じ名前空間、同じ名前の属性クラスを自分で定義してあげれば使えるということが判明しました。

namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class ExtensionAttribute : Attribute
    {

    }
}

BuildSuccess.png

ExtensionMethod.png

これを利用すれば自作の Enumerable クラスを定義することで LINQ が利用可能に。
夢が広がりんぐです。

おまけ

こうなってくると気になるのが、他の「属性を必要とする糖衣構文」です。

ということで省略可能引数は…?

OptionalParameter.png

あれ…?普通に使えました。
省略可能引数って OptionalAttribute 属性が必要では…?

なんと、OptionalAttribute クラスは .NET1.0 から含まれていました。

ΩΩΩ<な、なんだってー!?

VB.net では古くから省略可能引数がサポートされていたからなんですね。

次に dynamic。

public static class Hoge
{
    public static void Fuga(this string a, int b = 0, dynamic c = null)
    {

    }
}

DynamicAttributeNotFound.png

はい。拡張メソッドと一緒です。
System.Runtime.CompilerServices.DynamicAttribute クラスを定義してやると…

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
public sealed class DynamicAttribute : Attribute
{

}

DynamicParameter.png

おぉ、呼び出せました。

拡張メソッドに比べたら「どうしても dynamic を使いたい!」という場面は少ないと思いますが、覚えておいて損はないのではないでしょうか。

ついでに気になったので確認してみたところ、自作属性によって定義された拡張メソッドや dynamic を含む .NET2.0 の DLL を .NET3.5 以上がターゲットのプロジェクトから参照してみてもきちんと使えるのですね。

既にライブラリも(追記)

会社の先輩から既にライブラリがあることを教えて頂きました。

また、直後に Twitter でもタイムリーなネタが…

結構いまさらなネタだったんですねw

CallerMemberInfo (2014/05/09 追記)

ちなみに CallerMemberNameAttribute クラスを自前で定義した .NET4.0 のプロジェクトで以下のメソッドを作ってみたところ、メンバー名は渡ってきませんでした。残念。

public new void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
    // Livet の ViewModel.RaisePropertyChanged を呼び出す
    base.RaisePropertyChanged(propertyName);
}
19
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
19