RSCG- part 13 – IFormattable
name | IFormattable |
nuget |
https://www.nuget.org/packages/AOPMethodsCommon/ |
link | http://msprogrammer.serviciipeweb.ro/category/roslyn/ |
author | Andrei Ignat |
This will generate code to add IFormattable to any class, based on the properties of the class
The code that you start with is
[AutoMethods(CustomTemplateFileName = "CreateFormattable.txt", template = TemplateMethod.CustomTemplateFile)] partial class Department { public int ID { get; set; } public string Name { get; set; } } [AutoMethods(CustomTemplateFileName = "CreateFormattable.txt", template = TemplateMethod.CustomTemplateFile)] partial class Employee { public int ID { get; set; } public string Name { get; set; } public Department dep { get; set; } }
The code that you will use is
var e = new Employee(); e.ID = 1; e.Name = "Andrei"; e.dep = new Department(); e.dep.Name = "IT"; Console.WriteLine(e.ToString("for employee with id = {id} the name is {name} and department is {dep?.Name}", null)); e.dep = null; Console.WriteLine(e.ToString("for employee with id = {id} the name is {name} and department is {dep?.Name}", null));
The code that is generated is
[GeneratedCode("AOPMethods", "2021.2.27.640")] [DebuggerDisplay(" ID = {ID} Name = {Name} dep = {dep}")] partial class Employee: IFormattable{ public object ValueProperty(string val){ val = val.Replace("?",""); if(string.Compare("ID",val,StringComparison.CurrentCultureIgnoreCase)==0) { return this.ID; } if(string.Compare("Name",val,StringComparison.CurrentCultureIgnoreCase)==0) { return this.Name; } if(string.Compare("dep",val,StringComparison.CurrentCultureIgnoreCase)==0) { return this.dep; } throw new ArgumentException("cannot find "+ val); } //adapted from https://haacked.com/archive/2009/01/14/named-formats-redux.aspx/ private object Eval(string expression,IFormatProvider formatProvider) { if (expression.Contains(".")) { var splut = expression.Split("."); bool canBeNull=splut[0].Contains("?"); dynamic d = ValueProperty(splut[0]); if(canBeNull && d == null) return null; for(var i=1; i<splut.Length;i++){ canBeNull=splut[i].Contains("?"); d=d.ToString("{"+splut[i]+"}",formatProvider); if(canBeNull && d == null) return null; } return d; } return ValueProperty(expression); } public string ToString(string format, IFormatProvider formatProvider) { if (format == null) throw new ArgumentNullException("format"); List<object> values = new List<object>(); string rewrittenFormat = Regex.Replace(format, delegate (Match m) { Group startGroup = m.Groups["start"]; Group propertyGroup = m.Groups["property"]; Group formatGroup = m.Groups["format"]; Group endGroup = m.Groups["end"]; values.Add((propertyGroup.Value == "0") ? this : Eval(propertyGroup.Value, formatProvider)); int openings = startGroup.Captures.Count; int closings = endGroup.Captures.Count; return openings > closings || openings % 2 == 0 ? m.Value : new string('{', openings) + (values.Count - 1) + formatGroup.Value + new string('}', closings); }, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); return string.Format(formatProvider, rewrittenFormat, values.ToArray()); } }
Example Code: https://github.com/ignatandrei/RSCG_Examples/tree/main/IFormattable
Leave a Reply