У меня есть класс, который анализирует в данных из файла разделенного текста запятой. У меня есть перечисление для полей, чтобы помочь мне проанализировать данные в более легком. Класс, который анализирует все записи в общедоступных переменных хранений для каждого поля и конечно их типы переменных. Я должен получить тип этих переменных на основе данного перечисления.
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 местах. Существует ли способ обойти необходимость изменить это в обоих местах и сохранить ее как статический метод?
Если имя всегда будет соответствовать точно, вы можете сделать это с помощью отражения.
return typeof(DataBaseRecordInfo)
.GetProperty(field.ToString(), BindingFlags.Public | BindingFlags.Instance)
.PropertyType;
Вы сможете даже кэшировать эти значения в словаре, так что если найден, просто верните ввод словаря, в противном случае определите использование отражения и кэширования результата.
Да, вы можете использовать имена в 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;
}
};
Вы, вероятно, захотите кэшировать результат в словаре, поскольку отражение может быть дорогой производительностью.
Как насчет чего-то вроде этого:
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
, но я предполагаю, что вы имели в виду экземпляр Статический метод. Никто никогда не видит этот экземпляр.
Если вы хотите Свяжите значение 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());