Метод Расширения C# для проверки атрибутов

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

Я хочу протестировать против методов атрибута вещей как модели и контроллеры. Главным образом для проверки они имеют право attrbute т.е. Необходимый. Но я также использую это в качестве эксперимента с дополнительными методами и Лямбдами.

То, что я хотел бы, является методом что когда реализованные взгляды некоторая вещь как

Controller controller = new Controller();
controller.MethodName(params).HasAttribute<AttributeName>();

Методы расширения Iveused немного, но не до этого градуса.. Я уверен, что это должно быть достаточно просто сделать, но наклониться, кажется, добираются, мои дженерики и т.д. исправляют.

13
задан Andy Allison 13 August 2010 в 12:27
поделиться

6 ответов

Возможно, вы ищете это:

Controller controller = new Controller();
bool ok = controller.GetMethod(c => c.MethodName(null, null))
    .HasAttribute<AttributeName>();

Что хорошего в том, чтобы писать так, как это что у вас есть полная поддержка времени компиляции. Все остальные решения до сих пор используют строковые литералы для определения методов.

Вот реализации методов расширения GetMethod и HasAttribute :

public static MethodInfo GetMethod<T>(this T instance,
    Expression<Func<T, object>> methodSelector)
{
    // Note: this is a bit simplistic implementation. It will
    // not work for all expressions.
    return ((MethodCallExpression)methodSelector.Body).Method;
}

public static MethodInfo GetMethod<T>(this T instance,
    Expression<Action<T>> methodSelector)
{
    return ((MethodCallExpression)methodSelector.Body).Method;
}

public static bool HasAttribute<TAttribute>(
    this MemberInfo member) 
    where TAttribute : Attribute
{
    return GetAttributes<TAttribute>(member).Length > 0;
}

public static TAttribute[] GetAttributes<TAttribute>(
    this MemberInfo member) 
    where TAttribute : Attribute
{
    var attributes = 
        member.GetCustomAttributes(typeof(TAttribute), true);

    return (TAttribute[])attributes;
}
19
ответ дан 1 December 2019 в 22:38
поделиться

Вы ищете класс Reflection - он позволяет вам исследовать переданный объект.

Но, честно говоря, помимо обучающего упражнения, интерфейсы существуют для этого, если вы хотите, чтобы в модели было поле с именем Required или метод с именем IsRequired в контроллере, чем реализовывать в интерфейсе и требовать, чтобы этот интерфейс был реализован. .

Конкретно для атрибутов см. здесь :

Type t = something;
System.Console.WriteLine("Author information for {0}", t);
System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // reflection

foreach (System.Attribute attr in attrs)
{
    if (attr is Author)
    {
        Author a = (Author)attr;
            System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version);
    }
}
-1
ответ дан 1 December 2019 в 22:38
поделиться

Я не думаю, что вы сможете реализовать это в точности так, как вы описали. Часть MethodName (params) вашего оператора фактически выполнит метод, возвращая все, что возвращает метод, а не информацию о методе.

Что вы хотите сделать, так это передать MethodInfo в ваш класс расширения, используя отражение. Поэтому вместо вашего примера вы, вероятно, получите что-то вроде:

 controller.GetType().GetMethod(methodName).HasAttribute<AttributeName>();

Вероятно, вы могли бы упростить это до одного метода расширения в классе контроллера, инкапсулируя GetType (). GetMethod () , примерно так:

 controller.MethodHasAttribute(methodName, attributeName);
1
ответ дан 1 December 2019 в 22:38
поделиться

Вы можете проверить, имеет ли метод определенный атрибут, сделав следующее:

typeof(Controller).GetMethod("MethodName").GetAttributes<AttributeName>().Any();

Что касается самого метода расширения, при условии, что вы ищете метод расширения для типа Controller, как насчет чего-то вроде этого:

public static bool HasAttribute<A>(this Controller controller, string methodName)
{
   return controller.GetType().GetMethod(methodName).GetCustomAttributes(typeof(A), true).Any();
}

Помните, методы расширения вызываются на экземпляре, поэтому для использования этого вам все еще нужен экземпляр Controller:

var controller = new Controller();
Assert.IsTrue(controller.HasAttribute<AttributeName>("Method1"));
0
ответ дан 1 December 2019 в 22:38
поделиться

Использование:

bool hasAttribute = controller.HasMethodAttribute<TestAttribute>( "Test" )

Расширение:

public static bool HasMethodAttribute<TAttribute>( this object obj, string methodName )
{
    Type type = obj.GetType();

    MethodInfo method = type.GetMethod( methodName );
    if( method == null )
    {
        throw new ArgumentException( string.Format( 
            "Method '{0}' not found on object '{1}'", methodName, type.Name ) );
    }

    return method.GetCustomAttributes( typeof( TAttribute ), true ).Length > 0 ;
} 
1
ответ дан 1 December 2019 в 22:38
поделиться

Не могу точно сделать это с помощью методов расширения, но это близко:

public static class Program
{
  static void Main(string[] args)
  {
     Controller c1 = new Controller();
     Action a1 = c1.Method1;
     Console.WriteLine(a1.HasAttribute<Controller.TestAttribute>());
  }

  public static bool HasAttribute<T>(this Action method)
  {
     return method.Method.GetCustomAttributes(typeof(T), false).Any();
  }
}

class Controller
{
  [AttributeUsage(AttributeTargets.Method)]
  public class TestAttribute : System.Attribute
  {
  }

  [Test()]
  public void Method1()
  {
  }
}
1
ответ дан 1 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: