我的目标是生成string
。有以下条件。
首先,我将取一个空字符串,并根据长度开始构建字符串。
示例:
我有empty string
""
。
在第一步中,我想添加string
至8个字符,表示我的string
为""
,然后直到8个字符,我的字符串应包含值Hiwor
所以最后我的字符串将为Hiwor
如果没有值,则应在string
填充空值。
在第二步中,我想将字符串meena
添加到10个位置,因此我的最终字符串应为Hiwor meena
。这样我想建立我的字符串。何我可以做到这一点。你能帮我吗?
样品:
初始字符串""
首先将字符Hiwor
添加到8 positions
,
所以最终字符串应为Hiwor
第二步将字符串meena
添加到10 postions
所以最终字符串应为Hiwor meena
。
直到现在我尝试了这样
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);
}
}
}
但它给我一个例外。Index was out of range. Must be non-negative and less than the size of the collection.
答案 0 :(得分:3)
首先为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());
}
}
然后使用:
StringBuilder builder = new StringBuilder();
builder.AppendPadded("Hiwor", 8);
builder.AppendPadded("meena", 10);
return builder.ToString();
或者用你的例子:
foreach (string item in list)
builder.AppendPadded(item, transLine[item]);
编辑:好的,所以看起来你想要能够定义格式然后使用它来构建字符串。尝试:
(你需要为此引用System.ComponentModel.DataAnnotations和System.Reflection)
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; }
}
然后使用它:
MyItem item = new MyItem
{
ProductCode = "grouplife",
ApplicantFirstName = "meena",
ApplicantMiddleInitial = "d",
Partner = "yes",
Employee = "yes"
};
string paddedString = item.GetPaddedString();
读取字符串以获取项目:
MyItem item = AnItem.CreateFromPaddedString<MyItem>(paddedString);
答案 1 :(得分:0)
首先,我想谈谈你的例外情况:
指数超出范围。必须是非负数且小于集合的大小。
正如已经说过的例外。问题是您想要访问新StringBuilder sb
中不存在的位置。
StringBuilder sb = new StringBuilder();
在此行之后,您的新sb
为空。其中没有单一字符。因此,您只能访问位置0
的索引。但是,几乎在内部for-each循环的第一次迭代中,您希望将索引1
作为目标,并尝试将您的字符串插入到不存在的位置1
。
// length: 1 and item.Key: ProductCode
sb.Insert(length, item.Key);
那么如何解决这个问题。您可以使用String.Format()或C#6中的字符串插值功能。
例如:
<强> String.Format()
强>
var sb = new StringBuilder(string.Empty); // sb: []
sb.Append(string.Format("{0, -8}", "Hiwor")); // sb: [Hiwor ]
sb.Append(string.Format("{0,-10}", "meena")); // sb: [Hiwor meena ]
C#6字符串插值
var sb = new StringBuilder(string.Empty); // sb: []
sb.Append($"{"Hiwor", -8}"); // sb: [Hiwor ]
sb.Append($"{"meena", -10}"); // sb: [Hiwor meena ]
// ...
定位您的修改:
使用您给定的列表项,您将永远不会与任何词典键匹配。