Casting items of a collection with code generation

偶尔善良 提交于 2019-12-24 08:38:48

问题


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);
}

回答1:


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.



来源:https://stackoverflow.com/questions/9103387/casting-items-of-a-collection-with-code-generation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!