I'm using reflection to create a new instance Item B
from an instance of Item A
. These are different objects, but share some level of commonality. In this sample case, they both inherit from a base class.
Base Class:
public abstract class Common
{
public string Value { get; set; }
public virtual string Ignored { get; }
}
I then have two classes that I am working with, the original class, and the output:
public class Original : Common
{
public override string Ignored => "This will get ignored";
}
public class Output : Common { }
If I create a new instance of Original
and give the Value Property
a value, the I am able to see that value within one of the auto-generated backing fields. All of this using reflection, I can then use the Activator
to create an instance of my Output
class and am able to set the value of the Value Property
My process is to find the commonality, get all fields (properties if based on an interface) of that object, and then with the FieldInfo
I can read the value from Original
and set it in Output
.
My problem lies with the virtual
property called Ignored
, the backing field doesn't have a value, but if I read directly from the propertyinfo then I can get the value.
What am I missing with my understanding of how this following line is made up?
public override string Ignored => "This will get ignored";
Is it because it is an override? Or because it uses the =>
way of setting the property.
If this doesn't have an underlying field, what is the best way to match already used properties so that I only find those that don't have a backing field?
This is just test code at the moment, but for reference, this is basically my method:
private object CreateObject(object original, Type commonType, Type outputType)
{
BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
var response = Activator.CreateInstance(outputType, nonPublic: true);
if (commonType.IsInterface)
{
foreach (var info in commonType.GetProperties(flags))
{
object clonedValue = info.GetValue(original); //this is simplified for ease
var method = outputType.GetProperty(info.Name)?.GetSetMethod(nonPublic: true);
if (method != null)
method.Invoke(response, flags, null, new object[] { clonedValue }, null);
}
}
else
{
// ** This only gets the fields of the common type **
//foreach (var info in commonType.GetFields(flags))
//{
// object clonedValue = this.Clone(info.GetValue(original), implementations);
// info.SetValue(response, clonedValue);
//}
// ** Testing to get all fields of original type, and then its base type - based on the above commented out code
var fields = this.GetFieldsRecursive(original.GetType(), flags);
//var value = commonType.GetProperty("Ignored").GetValue(original); // Proves I can get the value from the original object
foreach (var info in fields)
{
object clonedValue = info.GetValue(original); // this is simplified for ease
info.SetValue(response, clonedValue);
}
}
return response;
}
I hope that makes sense
Any ability to help fill some gaps in my knowledge would be massively appreciated.
Aucun commentaire:
Enregistrer un commentaire