c# loop through all fields of enum assigning values from string array

I am building a Soap Body for a web-service, and there are dozens of optional fields.

Currently I have been handling these like this:

wsSoapBody.OrderType = aMessage[(int)cardCreate.OrderType].ToString();
wsSoapBody.ActivateFlag = Convert.ToInt32(aMessage[(int)cardCreate.ActivateFlag].ToString()); //P-02925;

if (aMessage[(int)cardCreate.ShipDate].ToString() != ""){
                wsSoapBody.ShipmentDate = Convert.ToDateTime(aMessage[(int)cardCreate.ShipDate].ToString()); //P-02925;
        }

wsSoapBody.ShipmentMethodCard = aMessage[(int)cardCreate.ShipMethodCard].ToString();
wsSoapBody.ShipmentMethodPin = aMessage[(int)cardCreate.ShipMethodPIN].ToString();

The CardCreate you see in those value assignments is an enumerated constant in the class cardCreate defined as below:

namespace EvryCardManagement
{
    class CardCreate
    {
        #region Variables

        private DCSSCardCreateType req;
        private DCSSCardCreateResponseType rsp;
        private DCSSCardCreate_V3_0Service stub;

        public string tokenID { get; set; }

        private enum cardCreate
        {
            MsgType = 0,
            MsgVersion = 1,
            WSName = 2,
            ReplyTo = 3,
            SourceSystem = 4,
            Timestamp = 5,
            UniqueMessageID = 6,
            SFDCContext = 7,
            InstitutionID = 8,
            CardNumber = 9,
            Version = 10,
            ProductID = 11,
            AccountNumber = 12,
            CustomerID = 13,
            CustomerNumber = 14,
            EmbossName1 = 15,
            Expiry = 16,
            FeeMonth = 17,
            ChargeAccountNo = 18,
            PINMethod = 19,
            CardFlag = 20,
            AddressTypeCard = 21,
            AddressTypePIN = 22,
            OrderType = 23,
            ActivateFlag = 24,
            ShipDate = 25,
            ShipMethodCard = 26,
            ShipMethodPIN = 27,
            FirstName = 28,
            LastName = 29,
            CardAddress1 = 30,
            CardAddress2 = 31,
            CardAddress3 = 32,
            CardAddress4 = 33,
            CardAddress5 = 34,
            CardAddress6 = 35,
            CardPostCode = 36,
            CardCity = 37,
            CardCountry = 38,
            PINName = 39,
            PINAddress1 = 40,
            PINAddress2 = 41,
            PINAddress3 = 42,
            PINAddress4 = 43,
            PINAddress5 = 44,
            PINAddress6 = 45,
            PINPostCode = 46,
            PINCity = 47,
            PINCountry = 48,
            Validfrom = 49,
            Note = 50,
            MakeCheckStatus = 51,
            EmbossName2 = 52,
            PAmount = 53,
            PAmountLength = 54,
            GKIndicator = 55,
            CreditLimit = 56,
            CardDesignNo = 57,
            ExtPictureID = 58,
            BulkID = 59,
            AccountNo2 = 60
        }

so, rather than doing them all one by one as I have been doing, is it possible to loop through the wsSoapBody (which is defined in the web-service) and for each one, get the corresponding value from the aMessage (which is defined as an array like this string[] aMessage )

EDIT

I have the below code to loop through, but I want to assign to the wsSoapBody and I am stuck:

foreach (cardCreate cItem in (cardCreate[])Enum.GetValues(typeof(cardCreate)))
 {
 }

(the above correction was suggested as an edit by Steve Lillis that was rejected due to a conflict)

so I don't know how then to assign the values to each element for example I want to set

wsSoapBody[cItem].value = aMessage[(int)CardCreate[cItem]` 

or I also tried:

wsSoapBody[cItem] = aMessage[(int)cItem].ToString();

but am having trouble making it work (or even compile) due to lack of knowledge

EDIT #2 :

I have also looked at GetNames as possibly I want the names and tried:

        foreach (string name in Enum.GetNames(typeof(cardCreate)))

        {
            wsSoapBody[name] = aMessage[(int)name].ToString();
        }

But I cannot apply indexing with [] to an expression of type 'DCSSCardCreateType'

thanks


Why not place the values onto the enum itself and then enumerate?

For example using System.ComponentModel Description attribute we can add that information to the enum itself such as:

public enum cardCreate
{
  [Description("General Response")]
  MsgType = 0,

  [Description("V2.0")]
  WSName = 2,

  [Description("OmegaMan")]
  ReplyTo = 3,

  [Description("Windows 10")]
  SourceSystem = 4,
}

So when we call a special method to enumerate the enum where we can extract that text and use it appropriately later such as:

myextensions.GetEnumValues<cardCreate>()
            .Select (ceEnum => new
                        {
                            Original   = ceEnum,
                            IndexValue = (int)ceEnum,
                            Text       = ceEnum.GetAttributeDescription()
                        })

The dynamic entity will look like this after the projection (the select):

Sweet! Now we have all the information in a easy consumable entity which provides all the information needed.

What? You need more than a string description? Then create a custom attribute on the enum and have all items/types of data to return as needed. For that see my blog article C# Using Extended Attribute Information on Objects.


Here are the extension methods used in the above example:

public static class myextensions
{
   public static IEnumerable<T> GetEnumValues<T>()
   {
       Type type = typeof( T );

       if (!type.IsEnum)
           throw new Exception( string.Format("{0} is not an enum.", type.FullName ));

       FieldInfo[] fields =
           type.GetFields( BindingFlags.Public | BindingFlags.Static );


       foreach (var item in fields)
           yield return (T)item.GetValue( null );
   }


  /// <summary>If an attribute on an enumeration exists, this will return that
   /// information</summary>
   /// <param name="value">The object which has the attribute.</param>
   /// <returns>The description string of the attribute or string.empty</returns>
   public static string GetAttributeDescription( this object value )
   {
       string retVal = string.Empty;
       try
       {
           retVal = value.GetType()
                         .GetField( value.ToString() )
                         .GetCustomAttributes( typeof( DescriptionAttribute ), false )
                         .OfType<DescriptionAttribute>()
                         .First()
                         .Description;

       }
       catch (NullReferenceException)
       {
           //Occurs when we attempt to get description of an enum value that does not exist
       }
       finally
       {
           if (string.IsNullOrEmpty( retVal ))
               retVal = "Unknown";
       }

       return retVal;
   }

}
链接地址: http://www.djcxy.com/p/91512.html

上一篇: VS代码自定义文件浏览器窗口颜色主题

下一篇: c#循环遍历从字符串数组中分配值的枚举字段