Skip to content

Instantly share code, notes, and snippets.

@yukitos
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yukitos/b75971276c1e17ad9ab6 to your computer and use it in GitHub Desktop.
Save yukitos/b75971276c1e17ad9ab6 to your computer and use it in GitHub Desktop.
Derived attribute type lost base type's attributes in F#
open System
open System.Reflection
[<AttributeUsage(AttributeTargets.All, AllowMultiple = true)>]
type MyAttribute() =
inherit Attribute()
// MyAttributeを継承しているのでAllowMultipleがtrueになっているはず。。。
type MyDerivedAttribute() =
inherit MyAttribute()
// テストしてみます
let debug (attr:AttributeUsageAttribute) = printfn "AllowMultiple = %b, Inherited = %b" (attr.AllowMultiple) (attr.Inherited)
let t1 = typedefof<MyAttribute>
let au1 = t1.GetCustomAttribute(typedefof<AttributeUsageAttribute>, true) :?> AttributeUsageAttribute
debug au1
printfn "-----"
let t2 = typedefof<MyDerivedAttribute>
let au2 = t2.GetCustomAttribute(typedefof<AttributeUsageAttribute>, true) :?> AttributeUsageAttribute
debug au2
// このコードの実行結果は:
// AllowMultiple = true, Inherited = true
// -----
// AllowMultiple = true, Inherited = true
// ところが以下のコードはコンパイルエラー:
// エラー FS0429: 属性の型 'MyDerivedAttribute' に 'AllowMultiple=false' があります。この属性を持つ複数のインスタンスは、単一の言語要素にアタッチできません。
[<MyDerived>]
[<MyDerived>]
type t = class end
using System;
using System.Reflection;
namespace ConsoleApplication3
{
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
class MyAttribute : Attribute
{
}
class MyDerivedAttribute : MyAttribute
{
}
// C# の場合はMyDerivedAttributeを複数指定してもエラーにならない
[MyDerived]
[MyDerived]
class MyDerived
{
}
class Program
{
static void debug(AttributeUsageAttribute attr)
{
Console.WriteLine("AllowMultiple = {0}, Inherited = {1}", attr.AllowMultiple, attr.Inherited);
}
static void Main(string[] args)
{
var au1 = typeof(MyAttribute).GetCustomAttribute(typeof(AttributeUsageAttribute), true) as AttributeUsageAttribute;
debug(au1);
Console.WriteLine("-----");
var au2 = typeof(MyDerivedAttribute).GetCustomAttribute(typeof(AttributeUsageAttribute), true) as AttributeUsageAttribute;
debug(au2);
// 結果は同じ:
// AllowMultiple = True, Inherited = True
// -----
// AllowMultiple = True, Inherited = True
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment