My aim is to generate a string
. which has following conditions.
First i will take an empty string and start building the string based on length.
Example:
I have an empty string
""
.
In the first step i want to add a string
till 8 characters, means first my string
is ""
then till 8 characters my string should contain the value Hiwor
so finally my string will be Hiwor
if there is no value empty value should be padded in the string
.
In the second step i want to add the string meena
till 10 positions , so my final string should be Hiwor meena
. In this way i want to build my string. Ho can i achieve this. Can you please help me.
Sample:
initial string ""
first step adding string Hiwor
till 8 positions
,
so final string should be Hiwor
second step adding string meena
till 10 postions
so final string should be Hiwor meena
.
Till now i tried like this
Dictionary<string, Int16> transLine = new Dictionary<string, Int16>();
transLine.Add("ProductCode", 1);
transLine.Add("ApplicantFirstName", 12);
transLine.Add("ApplicantMiddleInitial", 1);
transLine.Add("partner", 1);
transLine.Add("employee", 8);
List<string> list = new List<string>();
list.Add("grouplife");
list.Add("meena");
list.Add("d");
list.Add("yes");
list.Add("yes");
StringBuilder sb = new StringBuilder();
foreach (var listItem in list)
{
foreach (var item in transLine)
{
if (listItem == item.Key)
{
var length = item.Value;
sb.Insert(length, item.Key);
}
}
}
but it is throwing me an exception.Index was out of range. Must be non-negative and less than the size of the collection.
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);