2016-02-18 7 views
2

Я создаю сериализатор в C# (.NET 4.5, VS 2013), и я использую атрибут для управления метаданных сериализации, таких как имя для хранения член для чтения и письма. Поскольку я не хочу каждый раз выписывать имя члена как аргумент для атрибута, я пытаюсь использовать CallerMemberName.CallerMemberName не работает для конструктора атрибутов в поле

Для свойств он отлично работает: имя свойства передается при вызове конструктора, и этот атрибут позволяет присваивать значение свойства при десериализации.

Для полей, по какой-либо причине, CallerMemberName отказывается работать. Вместо этого я получаю строку по умолчанию. Каждый раз, когда параметры другого аргумента передаются правильно.

Мой текущий код для тестирования это:

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); 
    } 
} 

Я проверил его с поля, не получив никаких аргументов, с полем приема аргумент, чтобы убедиться, что конструктор вызывается с поля метания исключение конструктора, чтобы сделать так, чтобы вызывал конструктор, и я не могу понять, что я делаю неправильно.

ответ

2

Как MSDN государства, цитата:

Позволяет получить метод или свойство имя вызывающего абонента к методу .

Таким образом, вам нужно будет найти другой способ сделать то, что вы делаете, или придерживаться свойств.

+0

Имеет смысл, поскольку семантически поле не может вызвать ничего-_Caller_ в _CallerMemberName_ к нему не применимо. –

+0

Однако вызов конструктора не является явным ни в поле, ни в свойстве - и вызывается вызывающий конструктор атрибутов. Я полагаю, настоящая тайна - это то, что называют это в случае поля. Еще одна вещь, чтобы бросить на больную синтаксическую сахарную кучу Microsoft. –