【问题标题】:How can I pass an attribute parameter type with List<string> in C#?如何在 C# 中使用 List<string> 传递属性参数类型?
【发布时间】:2014-12-04 06:06:31
【问题描述】:

如何将列表传递给构造函数?

它显示一条消息:

错误 14 属性参数必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式

public class CustomAuthorize : AuthorizeAttribute {
    private List<string> multipleProgramID;

    //constructor
    public CustomAuthorize(List<string> _multipleProgramID) {
        multipleProgramID = _multipleProgramID;
    }
}

[CustomAuthorize(new List<string>(new string[] { ProgramList.SURVEY_INPUT, ProgramList.SURVEY_OUTPUT } ))]
[HttpPost]
public ActionResult DeleteWaterQualityItems(string sourceID, string wqID) {
    // ..other code...
}

public class ProgramList {
    public const string SURVEY_INPUT = "A001";
    public const string SURVEY_INPUT = "A002";
}

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    问题不在于将List&lt;string&gt; 传递给构造函数一般 - 问题在于您试图将它用于属性。你基本上不能这样做,因为它不是编译时常量。

    看起来ProgramList 实际上是一个枚举——所以你可能想把它变成一个枚举:

     [Flags]
     public enum ProgramLists
     {
         SurveyInput,
         SurveyOutput,
         ...
     }
    

    然后让你的CustomAuthorizeAttribute(应该这样命名,后缀为Attribute)在构造函数中接受ProgramLists。您可以将其指定为:

    [CustomAuthorize(ProgramLists.SurveyInput | ProgramLists.SurveyOutput)]
    

    然后,您可以使用单独的方法将每个 ProgramLists 元素映射到一个字符串,例如 "A001"。这可以通过对每个元素应用一个属性来完成,或者在某处有一个Dictionary&lt;ProgramLists, string&gt;

    如果您真的想继续使用这样的字符串,您可以让CustomAuthorizeAttribute 接受一个逗号分隔的列表,或者将其设为数组而不是列表并使用参数数组:

    [AttributeUsage(AttributeTargets.Method)]
    public class FooAttribute : Attribute
    {
        public FooAttribute(params string[] values)
        {
            ...
        }
    }
    
    [Foo("a", "b")]
    static void SomeMethod()
    {
    }
    

    【讨论】:

    • 2020 年,这还有很长的路要走吗?
    • @curiousBoy:是的,属性仍然不能使用列表。
    • 我认为 2021 年仍然如此。如果有人有更好的方法,请将其添加为答案。谢谢。
    【解决方案2】:

    你不能使用列表

    属性对参数和属性类型有限制,因为它们必须在编译时可用。 Using attributes in C#

    改用数组:

    //constructor
    public CustomAuthorize(string[] _multipleProgramID) 
    {
        ...
    }
    
    // usage
    [CustomAuthorize(new string[] { ProgramList.SURVEY_INPUT, ProgramList.SURVEY_OUTPUT })]
    

    【讨论】:

    • 编译器建议这是可能的 - 但由于某种原因,这个确切的代码(使用字符串而不是枚举)对我不起作用:(我遇到了同样的错误,只能使用常量表达式,类型和数组初始值设定项——这正是我所做的!必须使用字符串拆分,正如@blues_driven 所建议的那样。
    • 刚刚尝试过,它确实在 VS 2017 中编译,但它不一定对我有用 - 它必须对你有用:-)
    • 我试图将字符串数组参数作为 NUnut TestCase 参数传递。 [TestCase(new string[] {"a"})] public void TestMethod(string[] ab) - 这给了我Error CS0182 An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type。我刚刚弄清楚了原因。它无法确定我试图传递的参数 - 如果我创建一个包含我的字符串数组的对象数组,它可以工作:[TestCase(new object[] { new string[] { "a" } })]
    【解决方案3】:

    我试图做类似的事情,最后传递了一个逗号分隔的string 并在属性构造函数中使用string.Spilt(',') 将其转换为数组。

    【讨论】:

      【解决方案4】:

      您只需要在自定义属性构造函数中使用“params”关键字并将您的 programList 设为“enum”

      [CustomAttribute(ProgramList.SURVEY_INPUT, ProgramList.SURVEY_OUTPUT)]
      [HttpPost]
      public ActionResult DeleteWaterQualityItems(string sourceID, string wqID) {
          // ..other code...
      }
      

      在你的自定义属性类中使用这个

      public class CustomAuthorize : AuthorizeAttribute {
      
      //Constructor
      public CustomAuthorize (params ProgramList[] programListTypes) {
      
                  multipleProgramID= programListTypes;
              }
      
      private ProgramList[] multipleProgramID;
      
      }
      

      你枚举类

      public enum ProgramList : int
      {
      SURVEY_INPUT = 001;
      SURVEY_OUTPUT =002;
      
      }
      

      【讨论】:

        【解决方案5】:

        一种可能的选择:

           public class ConstraintExpectedValues : ConstraintAttribute
            {
        
                public ConstraintExpectedValues(object[] expectedValues)
                {
                    this.ExpectedValues = expectedValues;
                }
        
                public object[] ExpectedValues { get; set; }
            }
        

        用法:

        [ConstraintExpectedValues(new object[] {5,7,9})]
        

        【讨论】:

          猜你喜欢
          • 2015-11-20
          • 2010-12-30
          • 2020-08-26
          • 1970-01-01
          • 2011-11-30
          • 1970-01-01
          • 2016-06-28
          • 1970-01-01
          • 2011-02-05
          相关资源
          最近更新 更多