Hello
Definitely the use of reflection will affect performance. But I have some
suggestions to improve the performance of your application.
1 - passing -1, or (short)-1 to the setValue method will cause boxing to
occur because the are converted to object, then setValue will unbox them the
actually set the value of the field. Boxing will allocate heap memory for
every boxed value, and will take processor time to copy the value in heap.
Unboxing takes processor time to copy the value from the heap.
The unboxing is enevitable, but you can minimize the boxing by making a
static field of type object holding -1, and pass this object like this;
static object intM1 = -1;
static object shortM1 = (short)-1;
and in method fldInfo.SetValue(oDataEnt , intM1); or
fldInfo.SetValue(oDataEnt , shortM1);
This way boxing will occur 2 times only (for intM1 and shortM1) instead of
in every call to your method.
2 - If you try to call execute this line:
bool b = object.ReferenceEquals(aType.GetFields(), aType.GetFields());
you will find that b is false, which means that every time you call
GetFields a new array of FieldInfo objects is allocated. A way to solve this
is to make a static hashtable to cache the result of GetFields method in it.
So GetFields doesn't get executed every time., or better only cache the int
and short fields to save time wasted by testing the type of the field.
I recommend creating a static contructor and populate the hashtable with
arrays. So that the calls to GetFields are made just one time.
Below is how I do it (I have a similar application, but in mine i need to
set all DateTime fields to DateTime.MaxValue, and int values to int.MinValue
:) )
using System.Reflection;
using System.Collections;
class DataEntActivator
{
private static Hashtable FieldsTable;
private static object intM1;
private static object shortM1;
private class FieldsEntry
{
internal FieldInt[] intFlds;
internal FieldInt[] shortFlds;
ConstructorInfo cinfo;
FieldsEntry()
{
}
}
static DataEntActivator()
{
intM1 = -1;
shortM1 = (short)-1;
Assembly assembly = Assembly.Load("assemblyName");
Type[] allTypes = assembly.GetTypes();
FieldsTable = new Hashtable(allTypes.Length);
for(int i = 0; i < allTypes.Length; i++)
{
FieldInfo[] flds = allTypes[i].GetFields();
int intCount = 0, shortCount = 0;
for(int j = 0; j < flds.Length; j++)
{
if(flds[j].FieldType == typeof(int))
intCount++;
else if(flds[j].FieldType == typeof(short))
shortCount++;
}
FieldsEntry fe = new FieldEntry()
fe.intFlds = new FieldInfo[intCount];
fe.shortFlds = new FieldInfo[shortCount];
for(int j = 0; j < flds.Length; j++)
{
if(flds[j].FieldType == typeof(int))
fe.intFlds[--intCount] = flds[j];
else if(flds[j].FieldType == typeof(short))
fe.shortFlds[--shortCount] = flds[j];
}
fe.ConstructorInfo = allTypes[i].GetConstructor(Type.EmptyTypes);
fieldsTable.Add(allTypes[i], fe);
}
}
public static object CreateInstance(System.Type aType)
{
FieldsEntry fe = (FieldsEntry)FieldsTable[aType];
object oDataEnt = fe.ConstructorInfo.Info(null);
for(int i = 0; i < fe.intFlds.Length; i++)
{
fe.intFlds[i].SetValue(oDataEnt, intM1);
}
for(int i = 0; i < fe.shortFlds.Length; i++)
{
fe.shortFlds[i].SetValue(oDataEnt, shortM1);
}
return oDataEnt;
}
}
[quoted text, click to view] "Invalidlastname" <invalidlastname@toomanyvalidations.page> wrote in message
news:u$ZUfqtsDHA.536@tk2msftngp13.phx.gbl...
> Hi,
> In our project, we used XSD.exe to create the classes, not dataset, which
> represent the data entities from xsd files for passing among the tiers.
> We want to set the default value for all numeric fields to be -1 in our
data
> entity classes. I know this can be done by setting the default value
> attribute to -1, however, since we created the xsd directly from database
> views and in early development stage the schemas changes happened very
> often. Some custom set attributes can easily be lost. The solution we came
> up is to use reflections to set the default value for all numeric fields,
> shown below:
>
> My question is how costly to use Reflection to instantiate an object and
> examine every field, and probably assign the value to the field ?
>
>
> // class DataEntActivator
> public static object CreateInstance(System.Type aType)
>
> {
>
> object oDataEnt = Activator.CreateInstance(aType);
>
> FieldInfo[] flds = aType.GetFields();
>
> foreach (FieldInfo fldInfo in flds)
>
> {
>
> if (fldInfo.FieldType == typeof(short))
>
> {
>
> fldInfo.SetValue(oDataEnt , (short)-1);
>
> }
>
> else if (fldInfo.FieldType == typeof(int))
>
> {
>
> fldInfo.SetValue(oDataEnt , -1);
>
> }
>
> }
>
>
> return oDataEnt ;
>
> }
>
>
>
>
>
> // calling program
>
> MyDataEntity o =(MyDataEntity)
> DataEntActivator.CreateInstance(typeof(MyDataEntity)) ;
>
> // use o as a normal object
>
>
>
>