2016-11-20 2 views
0

Considérant le conditional attribute par défaut en C# fonctionne uniquement avec les méthodes void, j'essaie de construire mon propre.en essayant de construire un attribut conditionnel personnalisé en C#

mon code ci-dessous est availabe à http://ideone.com/FSOMKi aussi, je suis pas d'erreur de comiler, mais ressemble à quelque chose a mal tourné ici :(

using System; 
using System.Collections.Generic; // for HashSet 
using System.Linq; // for using Where 
using System.Reflection; 

namespace attribute 
{ 
public class Test 
{ 
    public static void Main() 
    { 
     var targetClasses = new HashSet<string>(new[] { "Foo", "Foo2" }); 
     var targetFns = new HashSet<string>(new[] { "fn", "fn2", "fn3" }); 

     foreach (var target in targetClasses){ 
      foreach(var fn in targetFns){ 
       var method = (target.GetType().GetTypeInfo()) // (typeof(Foo).GetTypeInfo()) 
       .DeclaredMethods.Where(x => x.Name == fn).FirstOrDefault(); 
       if (method != null) //return 0; 
       { 
       var customAttributes = (MyCustomAttribute[])method 
             .GetCustomAttributes(typeof(MyCustomAttribute), true); 
      if (customAttributes.Length > 0) 
      { 
       var myAttribute = customAttributes[0]; 
       bool value = myAttribute.condition; 
       Console.WriteLine(value); 
       if (value == true) 
        method.Invoke(null, null); 
       else 
        Console.WriteLine("The attribute parameter is not as required"); 
      } 
       } 
     } 
     } 
    } 
} 
} 


namespace attribute 
{ 
    [AttributeUsage(AttributeTargets.All)] 
    public class MyCustomAttribute : Attribute 
    { 
     public bool condition { get; set; } 
    } 


    public class Foo 
    { 
     [MyCustom(condition= true ? ("bar" == "bar") : false)] 
     internal static void fn() 
     { 
      Console.WriteLine("a function in a class"); 
     } 

     [MyCustom(condition= true ? (1 == 2) : false)] 
     internal static void fn2() 
     { 
      Console.WriteLine("another function in the same class"); 
     } 
    } 

    public class Foo2 
    { 
     [MyCustom(condition= true ? (1 == 1) : false)] 
     internal static void fn2() 
     { 
      Console.WriteLine("another function in a nother class"); 
     } 
    } 
} 

La sortie devrait être trois lignes comme suit:

fonction dans une classe Le paramètre d'attribut est pas nécessaire une autre fonction dans une classe utre

+2

Veuillez lire [ask] et expliquez ce que vous attendez de ce code, ce qu'il fait ou ne fait pas et ce que vous avez essayé de résoudre. – CodeCaster

Répondre

1

Votre question a besoin de beaucoup de refactoring.

Cependant, d'après ce que j'ai pu comprendre, vous construisez un attribut conditionnel personnalisé et le compilateur ne semble pas le savoir.

Le problème dans votre approche est que le ConditionalAttribute existant est le cas particulier en ce sens que le compilateur C# le sait. Le compilateur prend une action de compilation spéciale lorsque la méthode invoquée est décorée avec cet attribut. À cet égard, vous ne pouvez pas définir un autre attribut conditionnel simplement parce que le compilateur ne sera pas conscient de sa signification.

Sur une note connexe, ConditionalAttribute ne peut pas être appliqué à une méthode renvoyant non-vide car son application indique au compilateur de supprimer l'appel à la méthode. Le seul type de méthode que vous pouvez ignorer est la méthode à partir de laquelle vous ne vous attendez à rien - ce sont des méthodes retournant void et n'ayant aucun paramètre out.

+0

En outre, cette classe est "scellée" donc il n'est pas possible d'étendre son comportement (ce qui est logique, pour les raisons que vous avez mentionnées dans votre message) – Bidou

+0

@Bidou Exactement. Tout le comportement lié à cette classe est intégré dans le compilateur, ce qui ne laisse aucune place à la personnalisation. –

+0

Merci pour l'explosion. –