2015-08-20 8 views
1

Если у меня есть класс, определенный как это:приведения типа к классу

public class className 
{ 
    public object this[string propertyName] 
    { 
     get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } 
     set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } 
    } 

    public string Foo{ get; set; } 
    public string Bar { get; set; } 

Я могу, конечно, набор и получить значения, как это:

className d = new className(); 
d["Foo"]="abcd" // set 
string s = (string)f["Bar"]; 

(благодаря Eduardo Cuomo для его ответить here)

Но что я действительно хотел сделать что-то вроде:

Type target = Type.GetType(DocumentType); 

// loop through list of key-value pairs and populate the data class defined in target object Type 
foreach (Dictionary<string, string> PQList in LPQReq) 
{ 

foreach (KeyValuePair<string, string> kvp in PQList) 
{ 
    // populate the member in the data class with the value from the MQ String 
    target[kvp.Key] = kvp.Value;             
    }  

но это не компилировалось как Cannot apply indexing with [] to an expression of type 'System.Type'

так как я мог это сделать?

Конечно, я могу использовать dynamic, но, возможно, есть способ применить мой тип к моему целевому классу?

+3

'target' - это класс; что такое * экземпляр * этого класса, на котором вы хотели бы установить все эти свойства? – dasblinkenlight

+0

@dasblinkenlight: Ну, у меня более дюжины классов данных, поэтому я создаю тип, основанный на определении, указанном в строке 'DocumentType'. Это означает, что я могу заполнить все классы в целом, не указывая свойства и элементы ... –

+0

Получаете ли вы тип или нет, у вас нет экземпляра этого объекта. Даже вам это удастся, вы получите, что объект не настроен на ссылку объекта –

ответ

4

Вы можете сделать это с отражением. Предполагая, что все возможные DocumentType s иметь конструктор без параметров, вы можете сделать это следующим образом:

// Get the type (this comes from your example) 
Type target = Type.GetType(DocumentType); 
// Create an instance (that's the important part that was missing) 
object instance = Activator.CreateInstance(target); 
foreach (Dictionary<string, string> PQList in LPQReq) { 
    foreach (KeyValuePair<string, string> kvp in PQList) { 
     // This code again comes from your example, 
     // except propertyName is kvp.Key and value is kvp.Value 
     target.GetProperty(kvp.Key).SetValue(instance, kvp.Value, null); 
    } 
} 
+0

Спасибо, что предоставили мне отсутствующий экземпляр объекта = Activator.CreateInstance (target);' piece .. Я был бы прав в этом, без этого мой «target» не был создан? .. –

+1

@Banana 'target' является ['System.Type'] (https://msdn.microsoft.com/en-us/library/system.type (v = vs.110) .aspx) экземпляр, а не экземпляр этого типа. – CodeCaster

+0

@OurManInBananas Правильно, 'instance' - это объект, созданный из вашего типа' target'. – dasblinkenlight

3

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

Вы можете определить интерфейс:

public interface IIndexable_String 
{ 
    object this[string index] 
    { 
     get; 
     set; 
    } 
} 

применить его к классам:

public class someclass : IIndexable_String 

Затем создать экземпляр экземпляра и доступ к индексатор.

Type target = Type.GetType(DocumentType); 

// Instantiate 
IIndexable_String instance = (IIndexable_String)Activator.CreateInstance(target); 
foreach (Dictionary<string, string> PQList in LPQReq) 
{ 
    foreach (KeyValuePair<string, string> kvp in PQList) 
    { 
     // populate the member in the data class with the value from the MQ String 
     instance[kvp.Key] = kvp.Value;             
    } 

Конечно, если вы делаете это как @dasblinkenlight делает, не нужно даже магические методы получения и установки в классе, ни интерфейс.

+2

'instance [kvp.Key] = kvp.Value;' вместо 'target' –

+0

Thank вы очень за свою помощь, сейчас я собираюсь попробовать ответить @dasblinkenlight –

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