【问题标题】:Pass enum to method to be used as enum and type将枚举传递给用作枚举和类型的方法
【发布时间】:2011-04-06 20:53:43
【问题描述】:

我正在尝试将 Enum 传递给将为 gridview 创建列的方法。我可以将 Enum 作为 Enum passEnum OR Type enumType 传递,两者都可以,但不能一起使用。我的意思是,如果我将它作为类型传递,则 Enum.GetNames() 方法接受它,如果我将它作为枚举传递,则 StringEnum.GetString() 方法接受它。但是我不能通过一个并且让他们都接受它,我不能分别通过它们(枚举和类型)并且都接受它。 AMOST的工作方式:

public static void AddColumnsToGridView(GridView gv, Enum passEnum, Type enumType)
{
    BoundField bf = new BoundField();
    int c = 0;
    foreach (string item in Enum.GetNames(enumType))
    {
        bf = new BoundField();
        bf.HeaderText = StringEnum.GetString((passEnum)c);
        bf.DataField = item;
        bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
        bf.SortExpression = item;
        gv.Columns.Add(bf);
        c++;
    }
}

我在 passEnum 下看到一条红色的波浪线,上面写着:“找不到类型或命名空间‘passEnum’……等等”。出于某种原因,我可以让它在这样的方法之外工作:

BoundField bf = new BoundField();
int c = 0;
foreach (string item in Enum.GetNames(typeof(PatientRX)))
{
    bf = new BoundField();
    bf.HeaderText = StringEnum.GetString((PatientRX)c);
    bf.DataField = item;
    bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
    bf.SortExpression = item;
    gvRX.Columns.Add(bf);
    c++;
}

StringEnum.GetString() 方法获取附加到枚举的字符串值。它需要一个枚举传递给它。我怎样才能让它在一个方法中工作?

【问题讨论】:

    标签: gridview enums boundfield


    【解决方案1】:

    我通过为 StringEnum 类编写一个新方法来解决该问题,该方法返回枚举的字符串值列表,而不是尝试单独提取每个字符串......就像这样:

           public static void AddColumnsToGridView(GridView gv, Type enumType)
           {
               gv.Columns.Clear();
               List<string> headers = StringEnum.GetStringValueList(enumType);
               BoundField bf = new BoundField();
               int c = 0;
               foreach (string item in Enum.GetNames(enumType))
               {
                  bf = new BoundField();
                  bf.HeaderText = headers[c];
                  bf.DataField = item;
                  bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
                  bf.SortExpression = item;
                  gv.Columns.Add(bf);
                  c++;
                }
            }
    

    我更喜欢使用泛型,正如 Mike 所发布的那样......但是该行仍然存在问题:

    bf.HeaderText = StringEnum.GetString((TEnum)c);
    

    它调用的方法需要一个 Enum,而 Mike 的代码中所写的“enumType”显然不被视为 Enum,因为我收到错误“无法从 TEnum 转换为 System.Enum,这是它调用的方法:

            public static string GetString(Enum value)
            {
                string output = null;
                Type type = value.GetType();
    
                if (_stringValues.ContainsKey(value))
                    output = (_stringValues[value] as StringValueAttribute).Value;
                else
                {
                    //Look for our 'StringValueAttribute' in the field's custom attributes
                    FieldInfo fi = type.GetField(value.ToString());
                    StringValueAttribute[] attrs = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                    if (attrs.Length > 0)
                    {
                        _stringValues.Add(value, attrs[0]);
                        output = attrs[0].Value;
                    }
                }
                return output;
            }
    

    我没有写上面的方法(或 StringEnum 类)...但是这是我添加的用于获取枚举字符串列表的方法:

            public static List<string> GetStringValueList(Type enumType)
            {
                List<string> values = new List<string>();
                //Look for our string value associated with fields in this enum
                foreach (FieldInfo fi in enumType.GetFields())
                {
                    //Check for our custom attribute
                    var stringValueAttributes = fi.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[];
                    if (stringValueAttributes.Length > 0)
                    {
                        values.Add(stringValueAttributes[0].Value);
                    }
                }
                return values;
            }
    

    如果有人知道类似于 Mike 的方法(使用泛型),我可以完成这项工作,我将不胜感激。现在这完全是学习和知识的问题,因为我已经实现了上面的解决方案,但我仍然想知道如何以真正通用的方式做到这一点......谢谢!

    【讨论】:

      【解决方案2】:

      看起来您正在尝试在那里编写泛型方法,但实际上没有使用泛型,请尝试以下操作:

      public static void AddColumnsToGridView<TEnum>(GridView gv)
      {
          Type enumType = typeof(TEnum);
          BoundField bf = new BoundField();
          int c = 0;
          foreach (string item in Enum.GetNames(enumType))
          {
              bf = new BoundField();
              bf.HeaderText = StringEnum.GetString((Enum)c);
              bf.DataField = item;
              bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
              bf.SortExpression = item;
              gv.Columns.Add(bf);
              c++;
          }
      }
      

      这不是我真正从头开始做的方式,但它应该可以工作。

      编辑:对不起,我忘了展示一个调用它的例子,它看起来像这样:

      AddColumnsToGridView<MyEnumType>(gridView);
      

      编辑 2:我在下面的评论中提到,如果枚举不是从 0 开始或缺少值,您将遇到问题。你可能想试试这个:

      public static void AddColumnsToGridView(GridView gv, Type enumType)
      {
          Array values = Enum.GetValues(enumType)
          string[] names= Enum.GetNames(enumType)
      
          BoundField bf = new BoundField();
          for (int i = 0; i < names.Length; i++)
          {
              bf = new BoundField();
              bf.HeaderText = StringEnum.GetString((Enum)values.GetValue(i));
              bf.DataField = names[i];
              bf.ItemStyle.CssClass = "siteFont leftPaddingThree";
              bf.SortExpression = names[i];
              gv.Columns.Add(bf);
          }
      }
      

      请注意,这不再是通用方法,因为它不需要(这种方式更好 - 您不会在运行时为每个枚举类型获得多个版本的方法 JITted)。就这样称呼它:

      AddColumnsToGridView(gridView, typeof(MyEnum));
      

      我显然没有 StringEnum 的代码,所以我没有自己编译,但我认为应该没问题。如果问题仍然存在,请告诉我。

      【讨论】:

      • 感谢 Mike 的泛型课程,它很有帮助且非常有用,但仍有一个问题:bf.HeaderText = StringEnum.GetString((TEnum)c); 我收到错误“参数 1:无法从 'TEnum' 转换到'System.Enum'"
      • 抱歉,应该是 ((Enum)c) 而不是 ((TEnum)c) - 已编辑。使用这种方法可能会遇到的问题之一是枚举并不总是必须以 0 开头,并且它可能会丢失值,例如枚举可以定义为: public enum MyEnum { Value1 = 3, Value2 = 9 } 这将与上面的代码中断,因为您假设枚举值将从 0 开始并一次增加一个。
      • 我知道枚举值是关闭的,这肯定是个问题,但我不会为此使用具有指定值的枚举,只是标准值从 0 开始的枚举列表.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多