私は C# (.NET 4.5、VS 2013) でシリアライザーを作成しています。属性を使用して、読み取りと書き込みのためにメンバーを格納する名前など、シリアル化メタデータを制御しています。毎回属性の引数としてメンバー名を書き出すのは嫌なので、CallerMemberName を使用しようとしています。
プロパティの場合は問題なく動作します。コンストラクタが呼び出されるとプロパティ名が渡され、属性によって逆シリアル化でプロパティ値を割り当てることができます。
フィールドの場合、何らかの理由で、CallerMemberName は機能しません。代わりに、他の引数パラメーターが正しく渡されている場合でも、毎回デフォルトの string.Empty を取得しています。
これをテストするための私の現在のコードは次のとおりです。
class AttributeTest
{
[VariableAttribute(true)]
public string testField;
[VariableAttribute(false)]
public string testProperty { get; set; }
static void Main(string[] args)
{
Console.WriteLine("spawning");
AttributeTest test = new AttributeTest();
test.testField = "sdasd";
foreach (MemberInfo info in typeof (AttributeTest).GetMembers().Where(x => x.GetCustomAttribute(typeof(VariableAttribute)) != null))
{
//Console.WriteLine(info.Name);
VariableAttribute attr = (VariableAttribute)info.GetCustomAttribute(typeof (VariableAttribute));
Console.WriteLine(attr.testStore);
}
//Console.WriteLine(typeof(AttributeTest).GetMember("testField")[0].GetCustomAttributes().ElementAt(0));
test.testProperty = "falsdka";
Console.ReadKey();
}
}
[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
public class VariableAttribute : System.Attribute
{
public bool testStore;
public VariableAttribute(bool test = true, [CallerMemberName] string caller = "")
{
testStore = test;
Console.WriteLine(caller);
}
}
フィールドが引数を受け取らず、コンストラクターが呼び出されていることを確認するためにフィールドが引数を受け取り、コンストラクターが呼び出されていることを二重に確認するためにフィールドがコンストラクター例外をスローしてテストしましたが、わかりません私が間違っていることを出してください。