как я могу использовать потоки вместо stringbuilder в предварительно обработанном шаблоне t4 - PullRequest
3 голосов
/ 04 марта 2012

Мне нравится генерировать огромное количество текста с помощью предварительно обработанного шаблона T4.Было бы идеально, если TransformText ();метод записывает в пару вместо использования System.Text.StringBuilder GenerationEnvironment;в базовом классе.

Кто-нибудь знает, как переопределить это поведение?

1 Ответ

2 голосов
/ 04 марта 2012

Кажется, в сгенерированном коде нет ни одной предполагаемой точки расширения, которая позволила бы вам это сделать. Но если вы посмотрите на сгенерированный код, он будет выглядеть примерно так:

public partial class PreTextTemplate : PreTextTemplateBase
{
    public virtual string TransformText()
    {
        this.Write("some text");
        return this.GenerationEnvironment.ToString();
    }
}

public class PreTextTemplateBase
{
    protected StringBuilder GenerationEnvironment { get { … } set { … } }

    public void Write(string textToAppend)
    {
        // code to write to GenerationEnvironment
    }
}

Понятно, что вызов this.Write() предназначен для вызова метода Write() из базового класса. Но он не должен вызывать этот метод, вы можете скрыть его в не сгенерированной части класса:

public partial class PreTextTemplate
{
    private readonly StreamWriter m_streamWriter;

    public PreTextTemplate(StreamWriter streamWriter)
    {
        m_streamWriter = streamWriter;
    }

    public new void Write(string text)
    {
        m_streamWriter.Write(text);
    }
}

Если вы сделаете это, вызов TransformText() фактически напишет в StreamWriter, что именно то, что вы хотите.

В действительности, ваш код для метода Write() может быть более сложным, чтобы отразить то, что делает сгенерированный Write() (в основном это связано с отступом сгенерированного текста). Кроме того, базовый класс также содержит другие перегрузки Write(), которые вам также может потребоваться скрыть.

В качестве альтернативы, если вы не хотите отражать код в сгенерированном Write(), вы можете вызвать base.Write() в вашем Write(), записать содержимое StringWriter в ваш поток и затем очистить StringWriter. Но вам все равно придется иметь дело со всеми перегрузками Write().

...