I am trying to modify class instance members using reflection. I am having problem when trying to add/remove/display elements related to List
Following is the code.
[CODE]
class TestClass
{
public int i = 0;
public int IValue
{
get
{
return i;
}
set
{
i = value;
}
}
public List
}
class Program
{
static void Main(string[] args)
{
TestClass tcObject = new TestClass();
tcObject.i = 1;
tcObject.m_intList.Add(1);
tcObject.m_intList.Add(2);
// Following code modifies the field "I".
{
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"i",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
fieldInfo.SetValue(tcObject, 2);
System.Console.WriteLine("I value '{0}'", fieldInfo.GetValue(tcObject));
}
// Following code modifies the IValue property.
{
PropertyInfo propertyInfo = tcObject.GetType().
GetProperty(
"IValue",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
MethodInfo propertySetMethodInfo =
propertyInfo.GetSetMethod(true);
propertySetMethodInfo.Invoke(tcObject, new Object[] { 3 });
System.Console.WriteLine("Property IValue '{0}'", tcObject.i);
}
// Following is the actual problem I am having. I would like to add
// elements to the List member m_intList.
{
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"m_intList",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
// HOW do I add elements to m_intList using the fieldInfo object.
// I am trying to use reflection to modify values for the members.
// In my actual application I do not know the type i.e. whether it is List
// I will just have the tcObject. From the tcOBject I will get FieldInfo object corresponding to m_intList. Using this FieldINfo, // I should be able to add or remove elements.
foreach (int intItem in tcObject.m_intList)
{
System.Console.WriteLine("List Item value '{0}'", intItem);
}
}
}
}
[/CODE]
Thanks
Chandra
AlanPosted Oct 16, 2008, 2:19 PM
Here's a simple way to do it which relies on the fact that List implements the non-generic interface IList from which it gets an Add() method. As this Add method takes an object as a parameter it will work with both List and List:
using System.Collections;
//.........
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"m_intList",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
IList list = (IList)fieldInfo.GetValue(tcObject);
list.Add(3);
list.Add(4);
ChandraPosted Oct 16, 2008, 11:55 AM
class ListElement
{
public ListElement()
{
m_element = 0;
}
public ListElement(int element)
{
m_element = 1;
}
public int m_element;
}
class TestClass
{
public int i = 0;
public int IValue
{
get
{
return i;
}
set
{
i = value;
}
}
public List
public List
}
class Program
{
static void Main(string[] args)
{
TestClass tcObject = new TestClass();
tcObject.i = 1;
tcObject.m_intList.Add(1);
tcObject.m_intList.Add(2);
tcObject.m_lstElement.Add(new ListElement(1));
// Following code modifies the field "I".
{
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"i",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
fieldInfo.SetValue(tcObject, 2);
System.Console.WriteLine("I value '{0}'", fieldInfo.GetValue(tcObject));
}
// Following code modifies the IValue property.
{
PropertyInfo propertyInfo = tcObject.GetType().
GetProperty(
"IValue",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
MethodInfo propertySetMethodInfo =
propertyInfo.GetSetMethod(true);
propertySetMethodInfo.Invoke(tcObject, new Object[] { 3 });
System.Console.WriteLine("Property IValue '{0}'", tcObject.i);
}
{
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"m_intList",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
MemberInfo[] listMemberInfoArray = tcObject.GetType().GetMember("m_intList");
MemberInfo listMemberInfo = listMemberInfoArray[0];
MethodInfo addMethodInfo = fieldInfo.FieldType.GetMethod("Add");
object[] elementValue = { 5 };
addMethodInfo.Invoke(fieldInfo.GetValue(tcObject), elementValue);
foreach(int currElement in tcObject.m_intList)
{
System.Console.WriteLine("INt List element {0}", currElement);
}
Console.WriteLine();
}
{
FieldInfo fieldInfo = tcObject.GetType().
GetField(
"m_lstElement",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
MethodInfo addMethodInfo = fieldInfo.FieldType.GetMethod("Add");
Object listElementObject = Activator.CreateInstance(fieldInfo.
FieldType.
GetGenericArguments()[0]);
FieldInfo listElementFieldInfo = listElementObject.GetType().
GetField(
"m_element",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
listElementFieldInfo.SetValue(listElementObject, 2);
object[] elementValue = { listElementObject };
addMethodInfo.Invoke(fieldInfo.GetValue(tcObject), elementValue);
foreach (ListElement currListElement in tcObject.m_lstElement)
{
System.Console.WriteLine("List Item value '{0}'", currListElement.m_element);
}
}
}
}
ChandraPosted Oct 16, 2008, 10:23 AM
ChandraPosted Oct 16, 2008, 9:53 AM
AlanPosted Oct 16, 2008, 4:50 AM
Well, as things stand, you can add elements to the list with the following code:
FieldInfo fieldInfo = tcObject.GetType(). list = (List)fieldInfo.GetValue(tcObject);
GetField(
"m_intList",
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
List
list.Add(3);
list.Add(4);
When you say you don't know what kind of list it is in your actual application, is this because the field is of type List where T is a type parameter of the containing class or because it's of type List