Reputation: 3406
I'm doing code generation with C# and I would like to cast a backing field inside a getter.
Here is an example:
public class Potato
{
}
public class ProxyPotato : Potato
{
}
public class Stew
{
private ICollection<ProxyPotato> _proxyPotatoes;
//This is the code I would like to generate (specialy the cast part)
public ICollection<Potato> Potatoes { get { return _proxyPotatoes.Cast<Potato>().ToList(); } }
}
I have this code which can generate a property but I don't know how to execute a Cast:
private static void SetProperty(TypeBuilder builder, string propertyName, Type propertyType, FieldBuilder fieldBuilder)
{
const string GetterPrefix = "get_";
const string SetterPrefix = "set_";
// Generate the property
var propertyBuilder = builder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
// Property getter and setter attributes.
const MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
// Define the getter method.
var getterMethod = builder.DefineMethod(string.Concat(GetterPrefix, propertyName), propertyMethodAttributes, propertyType, Type.EmptyTypes);
// Emit the IL code.
// ldarg.0
// ldfld,_field
// ret
ILGenerator getterILCode = getterMethod.GetILGenerator();
getterILCode.Emit(OpCodes.Ldarg_0);
getterILCode.Emit(OpCodes.Ldfld, fieldBuilder);
getterILCode.Emit(OpCodes.Ret);
// Define the setter method.
MethodBuilder setterMethod = builder.DefineMethod(
string.Concat(SetterPrefix, propertyName),
propertyMethodAttributes, null, new Type[] { propertyType });
// Emit the IL code.
// ldarg.0
// ldarg.1
// stfld,_field
// ret
ILGenerator setterILCode = setterMethod.GetILGenerator();
setterILCode.Emit(OpCodes.Ldarg_0);
setterILCode.Emit(OpCodes.Ldarg_1);
setterILCode.Emit(OpCodes.Stfld, fieldBuilder);
setterILCode.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getterMethod);
propertyBuilder.SetSetMethod(setterMethod);
}
Upvotes: 1
Views: 208
Reputation: 171236
The cast extension method is a method call. You need to emit the following:
return Enumerable.ToList<Potato>(Enumerable.Cast<Potato>(_proxyPotatoes));
You can call these static methods using the OpCodes.Call instruction.
Upvotes: 3