transferindo valores de propriedades de um objeto para outro

Antes de tudo, eu sei sobre AutoMapper e não quero usá-lo. Porque eu estou aprendendo C # e quero ter uma visão profunda disso. Então, eu estou tentando resolver esse problema (explicado abaixo

No entanto, estou tentando criar uma copiadora de propriedades para lidar com valores das propriedades de um tipo para outro, se a propriedade tiver o mesmo nome e tipo e for legível da fonte e gravável no destino. Estou a usartype.GetProperties() método. O método de amostra está aqui:

    static void Transfer(object source, object target) {

        var sourceType = source.GetType();
        var targetType = target.GetType();

        var sourceProps = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        var targetProps = (from t in targetType,.GetProperties()
                           where t.CanWrite
                                 && (t.GetSetMethod().Attributes & MethodAttributes.Static) == 0
                           select t).ToList();

        foreach(var prop in sourceProps) {
            var value = prop.GetValue(source, null);
            var tProp = targetProps
                .FirstOrDefault(p => p.Name == prop.Name &&
                    p.PropertyType.IsAssignableFrom(prop.PropertyType));
            if(tProp != null)
                tProp.SetValue(target, value, null);
        }
    }

Funciona, mas li uma resposta no SO, usandoSystem.Reflection.Emit eILGenerator e delegados atrasados são mais rápidos e têm um desempenho superior. Mas não havia mais explicações ou links. Você pode me ajudar a entender maneiras de acelerar esse código? ou você pode me sugerir alguns links sobreEmit, ILGenerator e delegados atrasados por favor? Ou qualquer coisa que você acha que vai me ajudar a sujeitar? Desde já, obrigado

COMPELETE Q:

Compreendo e aprendo muitas coisas com a resposta de @ svick. Mas agora, se eu quiser usá-lo como um método genérico aberto, como posso fazer isso? algo assim

public TTarget Transfer<TSource, TTarget>(TSource source) where TTarget : class, new() { } 

ou uma extensão:

public static TTarget Transfer<TSource, TTarget>(this TSource source) where TTarget : class, new() { } 

questionAnswers(8)

yourAnswerToTheQuestion