|
using System;
using System.Collections.Generic;
namespace DynamicMethodsTest
{
//first sample class.
//Note - variables are private
class SampleA
{
private int m_value;
private List<string> m_list;
public SampleA(int a)
{
Value = a;
}
public int Value
{
get { return m_value; }
set { m_value = value; }
}
public List<string> List
{
get { return m_list; }
set { m_list = value; }
}
}
//second sample class
//note - completely different type, variable is private
class SampleB
{
private int m_anotherValue;
public SampleB(int a)
{
m_anotherValue = a;
}
}
class Program
{
static void Main(string[] args)
{
//create first test instance
SampleA sampleA = new SampleA(17);
//create get/set accessors that can work on int field "m_value" on any instance
AccessorBuilder.GetFieldValueUnboundDelegate<int, SampleA> valueGetter =
AccessorBuilder.CreateGetter<int, SampleA>("m_value");
AccessorBuilder.SetFieldValueUnboundDelegate<int, SampleA> valueSetter =
AccessorBuilder.CreateSetter<int, SampleA>("m_value");
//fetch value
int value = valueGetter(sampleA);
Console.WriteLine(value);
//change value
valueSetter(sampleA, 23);
Console.WriteLine(sampleA.Value);
//verify
value = valueGetter(sampleA);
Console.WriteLine(value);
//create get/set accessors for generic list field, they also can work on any instance
AccessorBuilder.GetFieldValueUnboundDelegate<List<string>, SampleA> listGetter =
AccessorBuilder.CreateGetter<List<string>, SampleA>("m_list");
AccessorBuilder.SetFieldValueUnboundDelegate<List<string>, SampleA> listSetter =
AccessorBuilder.CreateSetter<List<string>, SampleA>("m_list");
//get initial null reference
List<string> list = listGetter(sampleA);
Console.WriteLine(list);
list = new List<string>();
list.Add("aaa");
list.Add("bbb");
//modify
listSetter(sampleA, list);
//fetch and print
sampleA.List.ForEach(delegate(string item) { Console.WriteLine(item); });
//create instance bound delegates for list values
AccessorBuilder.GetFieldValueBoundDelegate<List<string>> instanceListGetter =
AccessorBuilder.CreateGetter<List<string>, SampleA>(sampleA, "m_list");
AccessorBuilder.SetFieldValueBoundDelegate<List<string>> instanceListSetter =
AccessorBuilder.CreateSetter<List<string>, SampleA>(sampleA, "m_list");
//note - we do not pass instance to delegate, it retrieves field value from sampleA
instanceListGetter().ForEach(delegate(string item) { Console.WriteLine(item); });
//modify
instanceListSetter(new List<string>(new string[]
{
"111",
"222"
}));
//verify
instanceListGetter().ForEach(delegate(string item) { Console.WriteLine(item); });
//demonstrate pseudo-polymorphic handling
//we have 2 classes, both expose (actually hide) int variable
//we can work with them like they both implement some interface
//define instance bound get/set accessors for int field of SampleA
AccessorBuilder.GetFieldValueBoundDelegate<int> instanceValueGetterA =
AccessorBuilder.CreateGetter<int, SampleA>(sampleA, "m_value");
AccessorBuilder.SetFieldValueBoundDelegate<int> instanceValueSetterA =
AccessorBuilder.CreateSetter<int, SampleA>(sampleA, "m_value");
SampleB sampleB = new SampleB(55);
//define instance bound get/set accessors for int field of SampleB
AccessorBuilder.GetFieldValueBoundDelegate<int> instanceValueGetterB =
AccessorBuilder.CreateGetter<int, SampleB>(sampleB, "m_anotherValue");
AccessorBuilder.SetFieldValueBoundDelegate<int> instanceValueSetterB =
AccessorBuilder.CreateSetter<int, SampleB>(sampleB, "m_anotherValue");
//store setters in type safe list
List<AccessorBuilder.SetFieldValueBoundDelegate<int>> uniformSet =
new List<AccessorBuilder.SetFieldValueBoundDelegate<int>>();
uniformSet.Add(instanceValueSetterA);
uniformSet.Add(instanceValueSetterB);
//store getters in type safe list
List<AccessorBuilder.GetFieldValueBoundDelegate<int>> uniformGet =
new List<AccessorBuilder.GetFieldValueBoundDelegate<int>>();
uniformGet.Add(instanceValueGetterA);
uniformGet.Add(instanceValueGetterB);
//initialize both variables to 43
uniformSet.ForEach(delegate(AccessorBuilder.SetFieldValueBoundDelegate<int> item) { item(43); });
//get and print
uniformGet.ForEach(
delegate(AccessorBuilder.GetFieldValueBoundDelegate<int> item)
{
int v = item();
Console.WriteLine("{0}={1}", item.Target.GetType().Name, v);
});
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am working with various Microsoft technologies since 1994 (remember Windows 3.1 ?
). Language of choice - C++/C#. I am mainly interested in software engineering and "generic solutions", so frequently I find myself designing / implementing frameworks and application skeletons, although sometimes I do various stuff from DB to Kernel Mode device drivers. I also love to understand why things are in the way they are, not just how to use them.
Currently I am Chief Software Architect and CTO of the software outsourcing company
mPrest Ltd , Israel.