代码之家  ›  专栏  ›  技术社区  ›  Robin Maben

将类的实例作为参数传递给属性构造函数

  •  14
  • Robin Maben  · 技术社区  · 14 年前

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

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

    有没有办法不用 new() 或者反射。

    5 回复  |  直到 14 年前
        1
  •  16
  •   Darin Dimitrov    14 年前

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

    另一方面,属性总是被反射所使用,所以我猜现在您正在检查类元数据上是否存在此自定义属性,您可以使用该实例。

        2
  •  3
  •   thangchung    14 年前

    不可能的人,你不能把实例,委托,lambda表达式传递给属性的构造函数。关于它的一些讨论 here

        3
  •  2
  •   Dean Chalk    14 年前

    您只能使用原语或原语数组作为属性参数,这是因为它们需要在编译时由编译器“排成一行”。

        4
  •  0
  •   kansaz    8 年前

    https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx 基于MSDN,如果需要在这里传递类的实例进行处理,则完全无法完成。

    属性参数仅限于 以下类型:简单类型(bool、byte、char、short、int、long, float和double)字符串系统。键入枚举对象( 对象类型的属性参数必须是 上述类型)任何上述类型的一维数组

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

        5
  •  0
  •   Nisarg Shah    7 年前

    为了访问非静态成员,需要在运行时实例化类。我有办法解决这个问题。如果要使用特定类的实例,可以基于列出的特定类型或表示为枚举的特定类型来管理实例化新实例。

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

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

      [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);
      }
      
    • 下面是负责为您创建正确实例的工厂模式:

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