Firstly define an extension method for StringBuilder:
public static class StringBuilderExtensions
{
public static void AppendPadded(this StringBuilder builder, string value, int length);
{
builder.Append($"{value}{new string(' ', length)}".Substring(0, length));
}
public static void AppendPadded(this StringBuilder builder, int value, int length);
{
builder.Append($"{new string('0', length)}{value}".Reverse().ToString().Substring(0, length).Reverse().ToString());
}
}
Then use:
StringBuilder builder = new StringBuilder();
builder.AppendPadded("Hiwor", 8);
builder.AppendPadded("meena", 10);
return builder.ToString();
Or with your example:
foreach (string item in list)
builder.AppendPadded(item, transLine[item]);
EDIT: Ok, so looks like you want to be able to define a format then build the string using it. Try:
(you will need to reference System.ComponentModel.DataAnnotations and System.Reflection for this)
public abstract class AnItem
{
private static int GetLength(PropertyInfo property)
{
StringLengthAttribute attribute = property.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault() as StringLengthAttribute;
if (attribute == null)
throw new Exception($"StringLength not specified for {property.Name}");
return attribute.MaxLength();
}
private string GetPropertyValue(PropertyInfo property)
{
if (property.PropertyType == typeof(string))
return property.GetValue(this);
else if (property.PropertyType == typeof(int))
return property.GetValue(this).ToString();
else
throw new Exception($"Property '{property.Name}' is not a supported type");
}
private static void SetPropertyValue(object item, PropertyInfo property, string value)
{
if (property.PropertyType == typeof(string))
property.SetValue(item, value, null);
else if (property.PropertyType == typeof(int))
property.SetValue(item, int.Parse(value), null);
else
throw new Exception($"Property '{property.Name}' is not a supported type");
}
public string GetPaddedString()
{
StringBuilder builder = new StringBuilder();
PropertyInfo[] properties = GetType().GetProperties();
foreach (PropertyInfo property in properties)
builder.AppendPadded(GetPropertyValue(property), GetLength(property));
return builder.ToString();
}
public static T CreateFromPaddedString<T>(string paddedString) where T : AnItem, new()
{
T item = new T();
int offset = 0;
PropertyInfo[] properties = typeof(T).GetProperties();
foreach (PropertyInfo property in properties)
{
int length = GetLength(property);
if (offset + length > paddedString.Length)
throw new Exception("The string is too short");
SetPropertyValue(item, property, paddedString.Substring(offset, length)));
offset += length;
}
if (offset < paddedString.Length)
throw new Exception("The string is too long");
return item;
}
}
public class MyItem : AnItem
{
[StringLength(1)]
public string ProductCode { get; set; }
[StringLength(12)]
public string ApplicantFirstName { get; set; }
[StringLength(1)]
public string ApplicantMiddleInitial { get; set; }
[StringLength(1)]
public string Partner { get; set; }
[StringLength(8)]
public string Employee { get; set; }
}
Then use it:
MyItem item = new MyItem
{
ProductCode = "grouplife",
ApplicantFirstName = "meena",
ApplicantMiddleInitial = "d",
Partner = "yes",
Employee = "yes"
};
string paddedString = item.GetPaddedString();
And to read a string to get an item:
MyItem item = AnItem.CreateFromPaddedString<MyItem>(paddedString);
9
solved Build the string dynamically based on the length in c#