C#, Получающий Тип Общедоступной переменной на основе Перечисления значений

У меня есть класс, который анализирует в данных из файла разделенного текста запятой. У меня есть перечисление для полей, чтобы помочь мне проанализировать данные в более легком. Класс, который анализирует все записи в общедоступных переменных хранений для каждого поля и конечно их типы переменных. Я должен получить тип этих переменных на основе данного перечисления.

public enum DatabaseField : int
    {
        NumID1 = 1,
        NumID2 = 2,
        NumID3 = 3,
    };

public class DataBaseRecordInfo
    {
        public long NumID1 { get; set; }
        public int NumID2 { get; set; }
        public short NumID3 { get; set; }

        public static Type GetType(DatabaseField field)
        {
           Type type;

           switch (field)
           {
               case DatabaseField.NumID1:
                   type = typeof(long);
                   break;
               case DatabaseField.NumID2:
                   type = typeof(int);
                   break;
               case DatabaseField.NumID3:
                   type = typeof(short);
                   break;
               default:
                   type = typeof(int);
                   break;
           }

           return type;
        }
     };

NumID1, NumID2, NumID3 всем присваивают в моем конструкторе. Однако я хочу получить эти типы, никогда не создавая экземпляр DataBaseRecordInfo. Прямо сейчас мой статический метод выше работал бы, однако, если бы я хотел изменить тип переменной, то я должен был бы изменить его в 2 местах. Существует ли способ обойти необходимость изменить это в обоих местах и сохранить ее как статический метод?

6
задан jsmith 22 January 2010 в 17:57
поделиться

4 ответа

Если имя всегда будет соответствовать точно, вы можете сделать это с помощью отражения.

return typeof(DataBaseRecordInfo)
    .GetProperty(field.ToString(), BindingFlags.Public | BindingFlags.Instance)
    .PropertyType;

Вы сможете даже кэшировать эти значения в словаре, так что если найден, просто верните ввод словаря, в противном случае определите использование отражения и кэширования результата.

4
ответ дан 17 December 2019 в 07:04
поделиться

Да, вы можете использовать имена в Enum вместе с отражением в типе данных databaseSeCordinfo, чтобы получить необходимые вами типы.

Это может быть сделано так:

public class DataBaseRecordInfo
{
    public long NumID1 { get; set; }
    public int NumID2 { get; set; }
    public short NumID3 { get; set; }

    public static Type GetType(DatabaseField field)
    {
        string name = field.ToString();
        Type recordType = typeof (DataBaseRecordInfo);
        var props = recordType.GetProperties();
        var matchedProperty = props.Where(p => name == p.Name).FirstOrDefault();
        if (matchedProperty == null)
            return null;    // We do not have a matching property.
        return matchedProperty.PropertyType;
    }
};

Вы, вероятно, захотите кэшировать результат в словаре, поскольку отражение может быть дорогой производительностью.

0
ответ дан 17 December 2019 в 07:04
поделиться

Как насчет чего-то вроде этого:

public static Type GetType(DatabaseField field)
{
  DataBaseRecordInfo dbri = new DataBaseRecordInfo();

  switch (field)
  {
    case DatabaseField.NumID1:
      return dbri.NumID1.GetType(); 
    case DatabaseField.NumID2:
      return dbri.NumID2.GetType(); 
    case DatabaseField.NumID3:
     return dbri.NumID3.GetType(); 
    default:
      return typeof(int);
  }
}

Я знаю, что вы сказали, что вы не должны были создать экземпляр databaseSercordinfo , но я предполагаю, что вы имели в виду экземпляр Статический метод. Никто никогда не видит этот экземпляр.

0
ответ дан 17 December 2019 в 07:04
поделиться

Если вы хотите Свяжите значение enum с какой-то дополнительной информацией, которую вы можете использовать свой собственный Customattribute.

Может быть, вам нужно что-то подобное:

public class DatabaseTypeAttribute : Attribute
{
    public DatabaseTypeAttribute(Type type)
    {
        Type = type;
    }
    public Type Type { get; private set; }
}

public enum DatabaseField : int
{
    [DatabaseType(typeof(long))]
    NumID1 = 1,
    [DatabaseType(typeof(int))]
    NumID2 = 2,
    [DatabaseType(typeof(short))]
    NumID3 = 3,
    NumID4 = 4,
};

public static class DatabaseFieldHelper
{
    public static Type GetDatabaseType(this DatabaseField field)
    {
        var attributes = (DatabaseTypeAttribute[])typeof(DatabaseField).GetField(Enum.GetName(typeof(DatabaseField), field))
            .GetCustomAttributes(typeof(DatabaseTypeAttribute), false);
        if (attributes.Length == 0)
            return typeof(int); //returns default type
        return attributes[0].Type;

    }
}

//prints: NumID1 database type: System.Int64
Console.WriteLine("NumID1 database type: {0}", DatabaseField.NumID1.GetDatabaseType());

//prints: NumID2 database type: System.Int32
Console.WriteLine("NumID2 database type: {0}", DatabaseField.NumID2.GetDatabaseType());

//prints: NumID3 database type: System.Int16
Console.WriteLine("NumID3 database type: {0}", DatabaseField.NumID3.GetDatabaseType());

//prints: NumID4 database type: System.Int32
Console.WriteLine("NumID4 database type: {0}", DatabaseField.NumID4.GetDatabaseType());
0
ответ дан 17 December 2019 в 07:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: