取得が面倒。
成果物
情報源
- https://docs.microsoft.com/ja-jp/dotnet/csharp/tour-of-csharp/attributes
- https://dobon.net/vb/dotnet/programing/typegetmembers.html
コード
属性の定義。
NameAttribute.cs
class NameAttribute : System.Attribute { public string Name { get; private set; } public NameAttribute(string name) => Name = name; }
属性の使用。
[Name("CCC")] class C {}
属性の取得。
class Main { public void Run() { ShowCClassAttrs(); } void ShowCClassAttrs() { foreach (NameAttribute attr in GetClassAttrs<C,NameAttribute>()) { Console.WriteLine($"{attr.Name}"); } } A[] GetClassAttrs<T,A>() { object[] objs = typeof(T).GetCustomAttributes(typeof(A), false); return Array.ConvertAll(objs, o => { return (A)o; }); } }
実行結果は以下。
CCC
全メンバ取得
[Name("Class")] class C { [Name("Field")] private int i; [Name("Property")] private int I { get; set; } [Name("Method")] private void M() {} [Name("コンストラクタ")] public C() {} [Name("デストラクタ")] ~C() {} [Name("列挙体の型定義")] enum E { e } [Name("構造体の型定義")] struct S {} [Name("デリゲートの型定義")] delegate void D(); }
using System; using System.Collections.Generic; using System.Reflection; class Main { public void Run() { ShowCClassAttrs(); ShowCClassMemberAttrs(); } void ShowCClassAttrs() { foreach (NameAttribute attr in GetClassAttrs<C,NameAttribute>()) { Console.WriteLine($"{attr.Name}"); } } A[] GetClassAttrs<T,A>() { object[] objs = typeof(T).GetCustomAttributes(typeof(A), false); return Array.ConvertAll(objs, o => { return (A)o; }); } void ShowCClassMemberAttrs() { foreach (NameAttribute attr in GetMemberAttrs<C,NameAttribute>()) { Console.WriteLine($"{attr.Name}"); } } A[] GetMemberAttrs<T,A>() { List<A> result = new List<A>(); MemberInfo[] members = typeof(T).GetMembers( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach (MemberInfo m in members) { object[] objs = m.GetCustomAttributes(typeof(A), false); result.AddRange(Array.ConvertAll(objs, o => { return (A)o; })); } return result.ToArray(); } }
実行結果は以下。
Class Method デストラクタ コンストラクタ Property Field 列挙体の型定義 構造体の型定義 デリゲートの型定義
所感
これにてMicrosoftのC#ツアー完了。なんか所々チュートリアルと被ってた感ある。ツアーでは基礎の基礎に触れた。地味に知らない重要なこともあったので、やって良かった。
ただ、ジェネリクスとかLINQとか、まだまだ重要なものに触れ足りない。MSDNのリンクは新章がまだまだあるので、順次やっていく。その前にツアー記事をまとめよう。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100 ※
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux