加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 用String []填充struct?

发布时间:2020-12-15 08:24:36 所属栏目:百科 来源:网络整理
导读:我正在解析CSV文件并将数据放在结构中.我正在使用 this question的TextFieldParser,它的工作方式就像一个魅力,除了它返回一个String [].目前我有一个丑陋的过程: String[] row = parser.ReadFields();DispatchCall call = new DispatchCall();if (!int.TryP
我正在解析CSV文件并将数据放在结构中.我正在使用 this question的TextFieldParser,它的工作方式就像一个魅力,除了它返回一个String [].目前我有一个丑陋的过程:
String[] row = parser.ReadFields();
DispatchCall call = new DispatchCall();
if (!int.TryParse(row[0],out call.AccountID)) {
    Console.WriteLine("Invalid Row: " + parser.LineNumber);
    continue;
}
call.WorkOrder = row[1];
call.Description = row[2];
call.Date = row[3];
call.RequestedDate = row[4];
call.EstStartDate = row[5];
call.CustomerID = row[6];
call.CustomerName = row[7];
call.Caller = row[8];
call.EquipmentID = row[9];
call.Item = row[10];
call.TerritoryDesc = row[11];
call.Technician = row[12];
call.BillCode = row[13];
call.CallType = row[14];
call.Priority = row[15];
call.Status = row[16];
call.Comment = row[17];
call.Street = row[18];
call.City = row[19];
call.State = row[20];
call.Zip = row[21];
call.EquipRemarks = row[22];
call.Contact = row[23];
call.ContactPhone = row[24];
call.Lat = row[25];
call.Lon = row[26];
call.FlagColor = row[27];
call.TextColor = row[28];
call.MarkerName = row[29];

结构包含所有这些字段作为字符串,除了AccountID是int.令我很生气的是,他们并没有强力打字,但现在就让我们看看.鉴于parser.ReadFields()返回一个String []是否有更有效的方法来填充结构(可能转换某些值,如row [0]需要成为一个int)与数组中的值?

**编辑:**我忘了提到的一个限制,可能影响什么样的解决方案将起作用,这个结构是[Serializable]并将在其他地方发送Tcp.

解决方法

您的里程数可能因其是否是更好的解决方案而有所不同,但您可以使用反射并定义用于标记结构成员的Attribute类.该属性将数组索引作为参数.然后,通过使用反射来分配右数组元素的值.

您可以像这样定义属性:

[AttributeUsage(AttributeTargets.Property)]
public sealed class ArrayStructFieldAttribute : Attribute
{
    public ArrayStructFieldAttribute(int index)
    {
        this.index = index;
    }

    private readonly int index;

    public int Index {
        get {
            return index;
        }
    }
}

这意味着该属性可以简单地用于将名为Index的int值与属性相关联.

然后,您可以使用该属性在结构中标记您的属性(只是一些示例性的行):

[ArrayStructField(1)]
public string WorkOrder { // ...

[ArrayStructField(19)]
public string City { // ...

然后可以使用结构类型的Type对象设置值(可以使用typeof运算符获取它):

foreach (PropertyInfo prop in structType.GetProperties()) {
    ArrayStructFieldAttribute attr = prop.GetCustomAttributes(typeof(ArrayStructFieldAttribute),false).Cast<ArrayStructFieldAttribute>().FirstOrDefault();
    if (attr != null) {
         // we have found a property that you want to load from an array element!
        if (prop.PropertyType == typeof(string)) {
            // the property is a string property,no conversion required
            prop.SetValue(boxedStruct,row[attr.Index]);
        } else if (prop.PropertyType == typeof(int)) {
            // the property is an int property,conversion required
            int value;
            if (!int.TryParse(row[attr.Index],out value)) {
                Console.WriteLine("Invalid Row: " + parser.LineNumber);
            } else {
                prop.SetValue(boxedStruct,value);
            }
        }
    }
}

此代码迭代结构类型的所有属性.对于每个属性,它会检查上面定义的自定义属性类型.如果存在此类属性,并且属性类型为string或int,则从相应的数组索引复制该值.

我正在检查字符串和int属性,因为这是您在问题中提到的两种数据类型.即使您现在只有一个特定的索引包含一个int值,如果此代码准备将任何索引作为字符串或int属性处理,那么它的可维护性也很好.

请注意,对于要处理的更多类型,我建议不要使用if和else if的链,而是使用Dictionary< Type,Func< string,object>>将属性类型映射到转换函数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读