C#のリフレクション:メンバーフィールドの属性の検索
-
03-07-2019 - |
質問
私はこれを間違って尋ねているかもしれませんが、クラス内のフィールドを自分自身内で見つけることができますか/どのようにできますか...たとえば...
public class HtmlPart {
public void Render() {
//this.GetType().GetCustomAttributes(typeof(OptionalAttribute), false);
}
}
public class HtmlForm {
private HtmlPart _FirstPart = new HtmlPart();
[Optional] //<-- how do I find that?
private HtmlPart _SecondPart = new HtmlPart();
}
または、これを間違って行っているだけかもしれません...メソッドを呼び出して、それ自体に適用されている属性を確認するにはどうすればよいですか
また、質問のため-親クラスを知らない/アクセスせずに属性情報を見つけることができるかどうか興味があります!
解決
あなたの質問を正しく理解していれば、あなたがしようとしていることは不可能だと思います...
Render
メソッドでは、オブジェクトに適用可能な属性を取得します。この属性はフィールド _SecondPart
に属し、クラス HtmlForm
に属します。
それを機能させるには、呼び出し元のオブジェクトを Render
メソッドに渡す必要があります。
public class HtmlPart {
public void Render(object obj) {
FieldInfo[] infos = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (var fi in infos)
{
if (fi.GetValue(obj) == this && fi.IsDefined(typeof(OptionalAttribute), true))
Console.WriteLine("Optional is Defined");
}
}
}
他のヒント
次の例は、単一のオブジェクトに、そのオブジェクトのパブリックフィールドまたはプライベートフィールドに特定のプロパティがあるかどうかを確認する方法を示しています。
var type = typeof(MyObject);
foreach (var field in type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance))
{
if (field.IsDefined(typeof(ObsoleteAttribute), true))
{
Console.WriteLine(field.Name);
}
}
質問の2番目の部分では、以下を使用して、現在のメソッドで属性が定義されているかどうかを確認できます。
MethodInfo.GetCurrentMethod().IsDefined(typeof(ObsoleteAttribute));
編集
編集内容に「はい」と答える場合、実際のタイプを知らなくても可能です。次の関数は、パラメータ型を取り、指定された属性を持つすべてのフィールドを返します。どこかで誰かが検索したいタイプを知っているか、検索したいタイプのインスタンスを持っているでしょう。
それなしで、Jon Skeetが言ったように、アセンブリ内のすべてのオブジェクトを列挙する必要があります。
public List<FieldInfo> FindFields(Type type, Type attribute)
{
var fields = new List<FieldInfo>();
foreach (var field in type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance))
{
if (field.IsDefined(attribute, true))
{
fields.Add(field);
}
}
return fields;
}
Type.GetFields
を使用してクラス内のフィールドを検索し、 MemberInfo.GetCustomAttributes
または IsDefined
を使用してフィールドに適用された属性を検索できます。 >-ただし、特定のタイプのすべてのフィールドを見つける必要がある場合は、次のようにする必要があります。
- 検索するすべてのアセンブリを反復処理する
- 各アセンブリ内のすべての型を反復処理します
- 各タイプ内のすべてのフィールドを反復処理します
- 各フィールドの属性の有無を確認します
今、本当に「これがオブジェクト」への参照であるフィールドに適用される特定の属性である「」を見つけようとしている場合、システム内のすべてのオブジェクトについてすべて知る必要があるため、それはさらに困難です。また、同じ値を持つ、つまり同じオブジェクトを参照する 2つのフィールドが存在する可能性があることにも留意してください。オブジェクトは「オプション」としてカウントされますか?その場合かどうか
基本的に、オブジェクトにプロパティが必要な場合(オプションかどうかなど)は、プロパティを含むフィールドではなく、オブジェクト自体のプロパティである必要があります。
あなたがやろうとしていることを間違って解釈している可能性がありますが、実行可能ではないか、少なくとも良い考えではないと疑います。ここで全体像を説明できますか?この属性で実際に何を達成しようとしていますか?