2015-09-14 4 views
0

Мне нужно создать объекты определенного типа во время выполнения (или указать конкретный тип).C# Создавать (или отличать) объекты определенного типа во время выполнения

У меня есть программа со словарем, содержащим имена атрибутов и объект.

Dictionary<string, Type> attributes = new Dictionary<string, Type>(); 

Этот словарь подается извне (во время выполнения)

пример:

attributes.Add("attrName1", typeof(string)); 
attributes.Add("attrName2", typeof(long)); 
attributes.Add("attrName3", typeof(DateTime)); 
attributes.Add("attrName4", typeof(ArrayList)); 

Программа должна извлекать данные (значения атрибутов) из источника и возврата в определенном типе ,

например:

The value of an attribute called "attrName1" needs to be returned as an object of type "string" 
The value of an attribute called "attrName2" needs to be returned as an object of type "long" 
The value of an attribute called "attrName3" needs to be returned as an object of type "DateTime" 
... 

Я написал функцию, которая возвращает атрибут как объект

public object GetTheValue(string AttribName) 
{ 
    object oReturn; 
    // do whatever to retreive the value of the attribute called <AttribName> and put it in oReturn 
    return oReturn; 
} 

Эта функция вызывается для каждого атрибута, чтобы получить его значение

object Buffer; 
object Val; 
foreach(KeyValuePair<string, Type> Attribute in attributes) 
{ 
    Buffer = GetTheValue(Attribute.Key); 

    //Here i need to cast/convert the "Buffer object to the typeof Attribute.Value 
    // Stuff I tried but doesn't work :( 
    // (Attribute.Value.GetType())Buffer; 
    // (typeof(Attribute.Value))Val 
    // Buffer as (Attribute.Value.GetType()) 
    // Buffer as (typeof(Attribute.Value)) 
    // Val = new (typeof(Attribute.Value))(Buffer) 
} 

Единственный вариант, который я вижу на данный момент, - это использование оператора switch, проходящего через все возможные типы и литье e возвратил объект к этому типу.

У кого-то есть другие варианты или решения?

+0

Вы получаете эту информацию из базы данных? Если да, рассмотрели ли вы использование ORM? Можете ли вы дать нам немного больше информации о том, как этот код будет использоваться? Я понимаю ваш код, но я не понимаю его необходимости. – xDaevax

+0

Как упоминалось в xDaevax, для большей цели могут быть более эффективные подходы к проблеме, но для текущего сценария, если все ваши типы являются базовыми типами (технически, если они реализуют 'IConvertible'), вы можете использовать' Convert.ChangeType () 'как в' var val = Convert.ChangeType (Buffer, Attribute.Value); ' –

+0

Вы можете использовать [.NET Reflection] (https://msdn.microsoft.com/en-us/library/f7ykdhsy (v = vs.110) .aspx) для создания объектов запрашиваемых типов во время выполнения. –

ответ

0

Почему бы не использовать что-то вроде:

Val = Convert.ChangeType(Buffer, typeof(Attribute.Value)); 
+0

Это, кажется, работает отлично, но только если я избавлюсь от typeof(), как это 'Val = Convert.ChangeType (Buffer, Attribute.Value);' – Davelicious

0

ChangeType работает только для типа, который реализован IConvertable интерфейс

работает только для типов, реализующих IConvertible интерфейс:

Для преобразования в success, значение должно реализовать интерфейс IConvertible , потому что метод просто завершает вызов соответствующему ICo обратимый метод. Метод требует, чтобы поддерживалось преобразование значения в conversionType.

Попробуйте использовать выражение, например:

Dictionary<string, Type> attributes = new Dictionary<string, Type>(); 
attributes.Add("attrName1", typeof(string)); 
attributes.Add("attrName2", typeof(long)); 
attributes.Add("attrName3", typeof(DateTime)); 
attributes.Add("attrName4", typeof(ArrayList)); 
object[] Items = new object[4]; 
Items[0] = "Test"; 
Items[1] = 11111L; 
Items[2] = new DateTime(); 
Items[3] = new ArrayList(); 
object Buffer; 
object Val; 
int i = 0; 
foreach(KeyValuePair<string, Type> attr in attributes) 
{ 
    Buffer = Items[i++]; 

    //Try this expression 
    var DataParam = Expression.Parameter(typeof(object), "Buffer"); 
     var Body = Expression.Block(Expression.Convert(Expression.Convert(DataParam, attr.Value), attr.Value)); 

     var Run = Expression.Lambda(Body, DataParam).Compile(); 
     var ret = Run.DynamicInvoke(Buffer); 


} 
Смежные вопросы