根据c#中的长度动态构建字符串

Build the string dynamically based on the length in c#

我的目标是生成一个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.

首先为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);

首先我想多说一下你的异常:

Index was out of range. Must be non-negative and less than the size of the collection.

如异常所述。问题是您想访问新 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     ]

// ...

针对您的编辑:

对于给定的列表项,您将永远无法与任何字典键匹配。