I'm trying to create an array using reflection, and insert values into it. I'm trying to do this for many different types so would like a createAndFillArray
function capable of this :
String propertyName1 = "prop1";
String propertyName2 = "prop2";
Type t1 = typeof(myType).getProperty(propertyName1).PropertyType.getElementType();
Type t2 = typeof(myType).getProperty(propertyName2).PropertyType.getElementType();
double exampleA = 22.5;
int exampleB = 43;
Array arrA = createAndFillArray(t1, exampleA);
Array arrB = createAndFillArray(t2, exampleB);
private Array createAndFillArray(Type t, object val){
Array arr = Array.CreateInstance( t, 1); //length 1 in this example only, real-world is of variable length.
arr.SetValue( val, 0 ); //this causes the following error: "System.InvalidCastException : Object cannot be stored in an array of this type."
return arr;
}
with the class A being as follows:
public class A{
public A(){}
private double val;
public double Value{
get{ return val; }
set{ this.val = value; }
}
public static implicit operator A(double d){
A a = new A();
a.Value = d;
return a;
}
}
and class B being very similar, but with int
:
public class B{
public B(){}
private double val;
public double Value{
get{ return val; }
set{ this.val = value; }
}
public static implicit operator B(double d){
B b = new B();
b.Value = d;
return b;
}
}
and myType is something like the following:
public class myType{
public A prop1{ get; set; }
public B prop2{ get; set; }
}
I hoped that the implicit operator would have ensured that the double be converted to class A, or the int to class B, and the error avoided; but this is obviously not so.
The above is used in a custom deserialization class, which takes data from a custom data format and fills in the corresponding .Net object properties. I'm doing this via reflection and at runtime, so I think both are unavoidable. I'm targeting the C# 2.0 framework.
I've dozens, if not hundreds, of classes similar to A
and B
, so would prefer to find a solution which improved on the createAndFillArray
method rather than a solution which altered these classes.
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.
Here's an example of using reflection to find the conversion method. So if you can get that method on your type and do the conversion your self.
Copied from: http://bytes.com/topic/c-sharp/answers/903775-getting-operators-using-reflection
//EndType is the type I want to PRODUCE
//StartType is the type I am pulling data FROM
MethodInfo mi = EndType.GetMethod(
"op_Implicit",
(BindingFlags.Public | BindingFlags.Static),
null,
new Type[] { StartType },
new ParameterModifier[0]
);
//Now if mi is NOT null, it means there is an operator that allows for converting StartType to EndType, if it is null, there isn't one
Casting is resolved at compile time, which in your case would be looking at at the type of the first parameter to Array.SetValue
which is of type object
, the 0 will be cast to type object
(ie. boxed).
Is there a reason that you need to use reflection? As others have posted you can do this with generics.
Here is an approximation of your reflection code using generics
private T[] createAndFillArray<T>(T val)
{
T[] array = new T[1];
array[0] = val;
return array;
}
Which you can call as follows
Array arrA = createAndFillArray<A>(exampleA);
Array arrB = createAndFillArray<B>(exampleB);
Based on your comment one possible implementation might be
private Array createAndFillArray(Type t, string property, object val)
{
object element = Activator.CreateInstance(t);
PropertyInfo pi = t.GetProperty(property);
if (pi != null)
{
pi.SetValue(element, val, null);
}
Array arr = Array.CreateInstance(t, 1);
arr.SetValue(element, 0);
return arr;
}
Which you can use as follows
Array arrB = createAndFillArray(t2, "Value", exampleB);
Where "Value" is the name of the property in the target type that you want to set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With