将Class的实例作为参数传递给Attribute构造函数

我需要在我的自定义属性中使用类/模型的实例(用于访问非静态成员)。

public class LoginModel { [AutoComplete(currentInstance)] //pass instance of class or CompanyNames public string DepartmentName { get; set; } public string[] DepartmentNames { get {...} } } 

有没有办法在不使用new()或Reflection的情况下执行此操作。

那是完全不可能的。 在编译时将属性烘焙到程序集的元数据中,因此讨论将实例传递给属性没有任何意义,因为实例仅在运行时存在。

另一方面,属性总是被reflection消耗,所以我猜你现在正在检查类元数据上是否存在这个自定义属性,你可以使用该实例。

不可能的人,你不能将实例,委托,lambda表达式传递给Attribute的构造函数。 有些人在这里讨论它

您只能使用基元或基元数组作为属性参数,这是因为它们需要在编译时由编译器“内联”。

https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx基于MSDN,如果你需要传递一个类的实例来处理它,它完全无法完成。

属性参数限制为以下类型的常量值:简单类型(bool,byte,char,short,int,long,float和double)字符串System.Type枚举对象(类型为object的属性参数的参数必须为上述类型之一的常数值。)任何上述类型的一维arrays

此外,你能解释为什么我们站在属性上下文中并需要从他们自己的对象获取信息。 这听起来很奇怪,因为我们经常使用Attribute来解释有关对象的更多信息,而不是阅读对象数据。

为了访问非静态成员,您需要在运行时实例化一个类。 我有一个解决方法。 如果要使用特定类的实例,可以设法根据列出或表示为枚举的特定类型实例化新实例。

我使用工厂模式,策略模式和reflection技术来做到这一点。 策略模式是实现不同的算法,用枚举类型包装每个类,而工厂类应负责注册所有类型的实现类,并根据定义的属性在运行时创建合适的类。 它可能在开始时很复杂,但后来明显得到它。 这是一个实际的例子:

  • 以下是枚举中表示的所有validation类型

     [Flags] public enum AlgorithmTypes { None = 0, All = 1, AtLeastOne = 2 } 
  • 现在将它们全部包含在策略模式中:

     public class NoneValidationMode : RequiredValidationMode { public NoneValidationMode() { } public override bool IsValid(string properties, object value) { //validation code here } } public class AllValidationMode: RequiredValidationMode { public override bool IsValid(string properties,object value) { //validation code here } } public class AtLeastOneValidationMode : RequiredValidationMode { public override bool IsValid(string properties, object value) { //validation code here } } public abstract class RequiredValidationMode { public abstract bool IsValid(string properties, object value); } 
  • 现在,这是Factory模式,负责为您创建正确的实例:

     public class AlgorithmStrategyFactory { private static ArrayList _registeredImplementations; static AlgorithmStrategyFactory() { _registeredImplementations = new ArrayList(); RegisterClass(typeof(NoneValidationMode)); RegisterClass(typeof(AllValidationMode)); RegisterClass(typeof(AtLeastOneValidationMode)); } public static void RegisterClass(Type requestStrategyImpl) { if (!requestStrategyImpl.IsSubclassOf(typeof(RequiredValidationMode))) throw new Exception("requestStrategyImpl must inherit from class RequiredValidationMode"); _registeredImplementations.Add(requestStrategyImpl); } public static RequiredValidationMode Create(AlgorithmTypes algorithmType) { // loop thru all registered implementations foreach (Type impl in _registeredImplementations) { // get attributes for this type object[] attrlist = impl.GetCustomAttributes(true); // loop thru all attributes for this class foreach (object attr in attrlist) { if (attr is AlgorithmAttribute) { if (((AlgorithmAttribute)attr).AlgorithmType.Equals(algorithmType)) { return (RequiredValidationMode)System.Activator.CreateInstance(impl); } } } } throw new Exception("Could not find a RequiredValidationMode implementation for this AlgorithmType"); } } 
  • 现在validation属性可以用于类,构造函数接受一个AlgorithmType,稍后将指定应该拾取和调用的算法。

     [AttributeUsage(AttributeTargets.Class, AllowMultiple =false)] public class MyAttribute : ValidationAttribute { AlgorithmTypes AlgorithmType; public MyAttribute(AlgorithmTypes algorithm = AlgorithmTypes.None) { AlgorithmType = algorithm; } public override bool IsValid(object value) { return (AlgorithmStrategyFactory.Create(AlgorithmType)).IsValid(Properties, value); } }