简体   繁体   English

通用方法并将任何枚举作为参数传递

[英]Generic method and passing any enum as parameter

All, 所有,

I'm trying to sort out my last bits in a Enum-framework. 我正在尝试整理枚举框架中的最后几位。

My goal: I want to send any enum type and convert it to a List and bind it to a drop down list. 我的目标:我想发送任何枚举类型并将其转换为List并将其绑定到下拉列表。 i will use an ObjectDataSource as DataSource for the given drop down list. 我将使用ObjectDataSource作为给定下拉列表的DataSource。 I want to create a composite control that only takes one parameter; 我想创建一个仅包含一个参数的复合控件; enum type. 枚举类型。 The composite control will sort out databinding and all other bits and bops. 复合控件将整理数据绑定以及所有其他位和结尾。

Now, the only problem I have is to convert the generic method to be compatible with the ObjectDataSource. 现在,我唯一的问题是将通用方法转换为与ObjectDataSource兼容。

Here is the code for my current method that i need to use on my ObjectDataSource. 这是我需要在ObjectDataSource上使用的当前方法的代码。 So, this method is working fine and returns a list of items for the Enum type WeekDays. 因此,此方法工作正常,并返回Enum类型WeekDays的项目列表。 However, I need the same functionality, but I need to replace WeekDays with any type of enum. 但是,我需要相同的功能,但是我需要用任何类型的枚举替换WeekDays。

Code: 码:

public class DropDownData
{

    public EnumDataItemList GetList()
    {
        EnumDataItemList items = new EnumDataItemList();

        foreach (int value in Enum.GetValues(WeekDays))
        {
            EnumDataItem item = new EnumDataItem();

            WeekDays d = (WeekDays)value;

            //Set display text
            if (!string.IsNullOrEmpty(DataHandlers.GetAttributeValue<DisplayTextAttribute, string>(d)))
            {
                //Translation logic goes here
                item.Text = DataHandlers.GetAttributeValue<DisplayTextAttribute, string>(d);
            }
            else
            {
                //Translation logic goes here
                item.Text = Enum.GetName(typeof(WeekDays), value);  
            }

            item.Value = value; //Actual value
            item.ToolTip = DataHandlers.GetAttributeValue<ToolTipAttribute, string>(d);
            item.Description = DataHandlers.GetAttributeValue<Lia.Library.Enums.CustomAttributes.DescriptionAttribute, string>(d);
            item.HelpText = DataHandlers.GetAttributeValue<HelpTextAttribute, string>(d);
            item.ExcludeOnBinding = DataHandlers.GetAttributeValue<ExcludeOnBinding, bool>(d);

            if (!item.ExcludeOnBinding)
            {
                items.Add(item);                    
            }
        }
        return items;
    }

}

public class EnumDataItemList : List<EnumDataItem>
{

}

As far as I know, I can't use a generic method with ObjectDataSOurce, but Generic Class is fine. 据我所知,我不能对ObjectDataSOurce使用通用方法,但是通用类很好。 I just can't get it to work with a generic class and all help is much appreciated. 我只是不能让它与泛型类一起使用,所有的帮助都值得赞赏。 When all is working, I'll be happy to share the complete solution. 一切正常后,我将很乐意分享完整的解决方案。

I'm using Framework 2.0. 我正在使用Framework 2.0。

This should help you. 这应该对您有帮助。 (Will throw Exception if T is not an enum type.) (如果T不是枚举类型,则将引发Exception。)

public static EnumDataItemList GetList<T>() where T : struct
{
    EnumDataItemList items = new EnumDataItemList();
    foreach (int e in Enum.GetValues(typeof(T)))
    {
       EnumDataItem item = new EnumDataItem();
       item.Text = Enum.GetName(typeof(T), e);
       item.Value = e;
    }
  //Rest of code goes here
}

Usage: 用法:

EnumDataItemList days = GetList<WeekDays>();

if you don't want to use a generic method, you can change it to: 如果您不想使用通用方法,可以将其更改为:

public static EnumDataItemList GetList(Type t)
{
        EnumDataItemList items = new EnumDataItemList();
        foreach (int e in Enum.GetValues(t))
        {
           EnumDataItem item = new EnumDataItem();
           item.Text = Enum.GetName(t, e);
           item.Value = e;
        }
      //Rest of code goes here
}

Alternative to Magnus', but the idea is pretty much exactly the same (just didn't want to throw it out after being beat to it ;-) ) - just iterates over the enum value rather than int. 替代了Magnus,但是这个想法几乎是完全一样的(只是不想在被击败之后将它扔掉;-))-只是遍历枚举值而不是int。 Same usage: 用法相同:

public static class DropDownData
{
    // struct, IComparable, IFormattable, IConvertible is as close as we'll 
    // get to an Enum constraint. We don't actually use the constraint for 
    // anything except rudimentary compile-time type checking, though, so 
    // you may leave them out.
    public static EnumDataItemList GetList<T>() 
            where T : struct, IComparable, IFormattable, IConvertible
    {
        // Just to make the intent explicit. Enum.GetValues will do the
        // type check, if this is left out:
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Type must be an enumeration");
        }

        EnumDataItemList items = new EnumDataItemList();

        foreach (Enum e in Enum.GetValues(typeof(T)))
        {
            EnumDataItem items = new EnumDataItem();

            // Note: This assumes the enum's underlying type is
            // assignable to Int32 (for example, not a long):
            int value = Convert.ToInt32(e);

            // The same attribute retrieval code as in the 
            // WeekDays example, including:
            item.Text = e.ToString(); // e is Enum here, no need for GetName
        }
    }
}

I seem to have gone at this problem a little differently and came up with something fairly terse that appears to work for me. 我似乎对这个问题的处理有些不同,并提出了一些简洁的方法,似乎对我有用。 I cannot claim this as original work since I don't remember if I found it and copied it, or if I put it together from bits and pieces I found, with some original work of my own. 我不能声称这是原始作品,因为我不记得自己是否找到并复制了它,或者是否将我发现的点点滴滴与自己的一些原始作品放在一起。 I put an extension method on enums that gives me a ToDisplayText function for getting my custom enum attribute of the same name. 我在枚举上添加了一个扩展方法,该方法为我提供了一个ToDisplayText函数,用于获取同名的自定义枚举属性。

    this.ddlBlah.DataSource =
      Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()
      .ToDictionary(x => x, x => x.ToDisplayText());
    this.ddlBlahs.DataValueField = "key";
    this.ddlBlah.DataTextField = "value";
    this.ddlBlah.DataBind();


public static string ToDisplayText(this Enum Value)
{
  try
  {
    Type type = Value.GetType();
    MemberInfo[] memInfo = type.GetMember(Value.ToString());

    if (memInfo != null && memInfo.Length > 0)
    {
      object[] attrs = memInfo[0].GetCustomAttributes(
                                    typeof(DisplayText),
                                    false);
      if (attrs != null && attrs.Length > 0)
        return ((DisplayText)attrs[0]).DisplayedText;
    }
  }
  catch (Exception ex)
  {
    throw new Exception("Your favorite error handling here");
  }
  return Value.ToString();

  // End of ToDisplayText()
}


[System.AttributeUsage(System.AttributeTargets.Field)]
public class DisplayText : System.Attribute
{
  public string DisplayedText;

  public DisplayText(string displayText)
  {
    DisplayedText = displayText;
  }

  // End of DisplayText class definition
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM