2016-02-18 2 views
2

Je produis un sérialiseur en C# (.NET 4.5, VS 2013), et j'utilise un attribut pour contrôler les métadonnées de sérialisation, comme le nom pour stocker un membre sous pour lire et écrire. Comme je ne veux pas écrire le nom du membre comme argument pour l'attribut à chaque fois, j'essaie d'utiliser CallerMemberName.CallerMemberName ne fonctionne pas pour le constructeur d'attribut sur un champ

Pour les propriétés, cela fonctionne correctement: le nom de la propriété est passé lorsque le constructeur est appelé, et l'attribut me permet d'affecter la valeur de la propriété à la désérialisation.

Pour les champs, quelle qu'en soit la raison, CallerMemberName refuse de fonctionner. Au lieu de cela, j'obtiens la chaîne par défaut.Empty à chaque fois, même lorsque les autres paramètres d'argument passent correctement.

Mon code actuel pour tester c'est:

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

Je l'ai testé avec le champ recevant pas d'arguments, avec le champ recevant un argument pour vous assurer que le constructeur est appelé, avec le lancement sur le terrain une exception constructeur pour rendre doublement sûr l'appel du constructeur, et je n'arrive pas à comprendre ce que je fais de mal.

Répondre

2

Comme MSDN états, citation:

vous permet d'obtenir le nom de la méthode ou de la propriété de l'appelant à la méthode .

Vous devrez donc trouver une autre façon de faire ce que vous faites, ou vous en tenir aux propriétés.

+0

Fait logique, car un champ ne peut rien appeler sémantiquement - _Caller_ dans _CallerMemberName_ ne lui est pas applicable. –

+0

L'appel au constructeur n'est cependant pas explicite dans le champ ou la propriété - et le constructeur d'attribut IS est appelé. Je suppose que le vrai mystère est ce qui l'appelle dans le cas du champ. Juste une chose de plus à jeter sur la pile de sucre syntaxique maladive de Microsoft. –