在UWP中尝试使用T4的朋友们可能会注意到,VS设计器默认生成的运行时T4无法通过编译,因为他使用了一些不支持UWP的API,解决方案也很简单,知道将其复制出来,修正不兼容的部分,指定inherits参数为新的基类即可,这里提供一个简单的版本,应该还可以优化
public class FormatterBase { private bool _endsWithNewline; private StringBuilder _generationEnvironmentField; private List<int> _indentLengthsField; protected StringBuilder GenerationEnvironment { get { if ((_generationEnvironmentField == null)) { _generationEnvironmentField = new StringBuilder(); } return _generationEnvironmentField; } set { _generationEnvironmentField = value; } } /// <summary> /// A list of the lengths of each indent that was added with PushIndent /// </summary> private List<int> IndentLengths { get { if ((_indentLengthsField == null)) { _indentLengthsField = new List<int>(); } return _indentLengthsField; } } /// <summary> /// Gets the current indent we use when adding lines to the output /// </summary> public string CurrentIndent { get; private set; } = ""; /// <summary> /// Current transformation session /// </summary> public virtual IDictionary<string, object> Session { get; set; } public virtual string TransformText() { GenerationEnvironment.Clear(); Render(); return string.Empty; } protected virtual void Render() { } #region Transform-time helpers /// <summary> /// Write text directly into the generated output /// </summary> public void Write(string textToAppend) { if (string.IsNullOrEmpty(textToAppend)) { return; } // If we're starting off, or if the previous text ended with a newline, // we have to append the current indent first. if (((GenerationEnvironment.Length == 0) || _endsWithNewline)) { GenerationEnvironment.Append(CurrentIndent); _endsWithNewline = false; } // Check if the current text ends with a newline if (textToAppend.EndsWith(Environment.NewLine, StringComparison.CurrentCulture)) { _endsWithNewline = true; } // This is an optimization. If the current indent is "", then we don't have to do any // of the more complex stuff further down. if ((CurrentIndent.Length == 0)) { GenerationEnvironment.Append(textToAppend); return; } // Everywhere there is a newline in the text, add an indent after it textToAppend = textToAppend.Replace(Environment.NewLine, (Environment.NewLine + CurrentIndent)); // If the text ends with a newline, then we should strip off the indent added at the very end // because the appropriate indent will be added when the next time Write() is called if (_endsWithNewline) { GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - CurrentIndent.Length)); } else { GenerationEnvironment.Append(textToAppend); } } /// <summary> /// Write text directly into the generated output /// </summary> public void WriteLine(string textToAppend) { Write(textToAppend); GenerationEnvironment.AppendLine(); _endsWithNewline = true; } /// <summary> /// Write formatted text directly into the generated output /// </summary> public void Write(string format, params object[] args) { Write(string.Format(CultureInfo.CurrentCulture, format, args)); } /// <summary> /// Write formatted text directly into the generated output /// </summary> public void WriteLine(string format, params object[] args) { WriteLine(string.Format(CultureInfo.CurrentCulture, format, args)); } /// <summary> /// Increase the indent /// </summary> public void PushIndent(string indent) { if ((indent == null)) { throw new ArgumentNullException(nameof(indent)); } CurrentIndent = (CurrentIndent + indent); IndentLengths.Add(indent.Length); } /// <summary> /// Remove the last indent that was added with PushIndent /// </summary> public string PopIndent() { var returnValue = ""; if ((IndentLengths.Count > 0)) { var indentLength = IndentLengths[(IndentLengths.Count - 1)]; IndentLengths.RemoveAt((IndentLengths.Count - 1)); if ((indentLength > 0)) { returnValue = CurrentIndent.Substring((CurrentIndent.Length - indentLength)); CurrentIndent = CurrentIndent.Remove((CurrentIndent.Length - indentLength)); } } return returnValue; } /// <summary> /// Remove any indentation /// </summary> public void ClearIndent() { IndentLengths.Clear(); CurrentIndent = ""; } #endregion #region ToString Helpers /// <summary> /// Utility class to produce culture-oriented representation of an object as a string. /// </summary> public class ToStringInstanceHelper { private IFormatProvider _formatProviderField = CultureInfo.InvariantCulture; /// <summary> /// Gets or sets format provider to be used by ToStringWithCulture method. /// </summary> public IFormatProvider FormatProvider { get { return _formatProviderField; } set { if ((value != null)) { _formatProviderField = value; } } } /// <summary> /// This is called from the compile/run appdomain to convert objects within an expression block to a string /// </summary> public string ToStringWithCulture(object objectToConvert) { if ((objectToConvert == null)) { throw new ArgumentNullException(nameof(objectToConvert)); } var t = objectToConvert.GetType(); var method = t.GetMethod("ToString", new[] { typeof (IFormatProvider) }); //if ((method == null)) //{ return objectToConvert.ToString(); //} //return ((string) (method.Invoke(objectToConvert, new object[] //{ // _formatProviderField //}))); } } /// <summary> /// Helper to produce culture-oriented representation of an object as a string /// </summary> public ToStringInstanceHelper ToStringHelper { get; } = new ToStringInstanceHelper(); #endregion }