Приведение предметов коллекции с генерацией кода - PullRequest
1 голос
/ 02 февраля 2012

Я делаю генерацию кода с C #, и я хотел бы привести вспомогательное поле внутри геттера.

Вот пример:

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

У меня есть этот код, который может генерировать свойство, но я не знаю, как выполнить приведение:

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 Ответ

3 голосов
/ 02 февраля 2012

Метод расширения приведения является вызовом метода.Вам нужно выдать следующее:

return Enumerable.ToList<Potato>(Enumerable.Cast<Potato>(_proxyPotatoes));

Вы можете вызывать эти статические методы, используя инструкцию OpCodes.Call.

...