2012-02-01 3 views
1

Я делаю генерацию кода с помощью 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); 
} 
+0

Это не литье. Это просто вызов статического метода [Enumerable.Cast ] (http://msdn.microsoft.com/en-us/library/bb341406.aspx). – dtb

+0

Мне просто интересно, каков контекст, на котором вы фактически работаете? Мне никогда не приходилось делать что-либо подобное и хотелось бы знать, когда он вступает в игру. –

+0

@dtb Вы правы! Я переименую вопрос в: Как использовать OpCodes.Call для генерации эквивалента Cast () – W3Max

ответ

3

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

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

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

+2

Правильно, и имейте в виду, что это 'Enumerable.ToList (Enumerable.Cast (_proxyPotatoes));': компилятор обычно будет автоматически предоставлять общий аргумент здесь, но если вы сделав это вручную, вам нужно указать его. – hvd

+0

@hvd Я отредактировал это. Я забыл, потому что я никогда не пишу его таким образом ;-) – usr

+1

Вы правы! Я переименую вопрос в: Как использовать OpCodes.Call для emit return Enumerable.ToList (Enumerable.Cast (_proxyPotatoes)); Извините, но я новичок с генерацией кода! – W3Max

 Смежные вопросы

  • Нет связанных вопросов^_^