Stringbuilder в CIL (MSIL)

Я добавил бы следующие новые поля к вышеупомянутой таблице:

  • thread_id: идентификатор для всех комментариев, присоединенных к конкретному объекту

  • дата: дата комментария (позволяет выбирать комментарии в порядке)

  • разряд: разряд комментария (позволяет выбирать порядок комментария путем рейтинга)

Используя эти поля Вы будете в состоянии:

  1. выборка все комментарии в потоке в единственном op
  2. заказывают комментарии в потоке или по дате или разряд

, К сожалению, если Вы хотите сохранить свой DB запросов близко к стандарту SQL, необходимо будет воссоздать дерево в памяти. Некоторый DBS предлагает специальные запросы для иерархических данных (f.e. Oracle)

./alex

5
задан Josh 20 October 2009 в 20:08
поделиться

1 ответ

Любые свойства, являющиеся типами значений ( int и т. Д.), Нуждаются в упаковке; или вам нужно будет использовать другую перегрузку Append .

Также:

  • вам нужно загружать объект каждый раз (arg0)
  • StringBuilder.Append - это свободный API; вам нужно либо вставить значение, либо повторно использовать его:
  • как следствие, вам не нужно поле

(хотя лично я бы вернул строку , но "meh")

Примерно так:

    DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>();
    MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder

    var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true);
    var generator = method.GetILGenerator();
    generator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); //make our string builder 
    //iterate through all the instance of T's props and sb.Append their values.
    PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
    foreach (var info in props)
    {   
        generator.Emit(OpCodes.Ldarg_0);
        generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter
        if (info.PropertyType.IsValueType)
        {
            generator.Emit(OpCodes.Box, info.PropertyType);
        }
        generator.Emit(OpCodes.Callvirt, AppendMethod);        //Call Append 
    }
    generator.Emit(OpCodes.Ret);           //return pointer to sb

Это создает эквивалент:

StringBuilder ClassWriter(T obj) {
    return new StringBuilder.Append((object)obj.Foo).Append((object)obj.Bar)
                   .Append((object)obj.Blip).Append((object)obj.Blap);
}
5
ответ дан 14 December 2019 в 19:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: