C# c“结构字段为”;从未分配给;警告
基于,我创建了一个DLL,可以读取不同的文件类型。我也有成功运行的单元测试。我创建一个结构并将其用作泛型类型 无论如何,当我编译时,我在每个struct字段上都会得到一个警告。例如:字段“FileReader.Tests.CsvReader.Record.Field1”从未分配给,并且其默认值始终为0 事实上,我正在使用SetValueDirect()设置值,当我运行测试或调试代码时,我可以验证这一点。为什么它会给我这个错误,我怎样才能避免或修复它 下面是一些基本代码,让您了解一些情况。我猜我没有提供足够的信息,但希望有人能提供线索C# c“结构字段为”;从未分配给;警告,c#,generics,struct,C#,Generics,Struct,基于,我创建了一个DLL,可以读取不同的文件类型。我也有成功运行的单元测试。我创建一个结构并将其用作泛型类型 无论如何,当我编译时,我在每个struct字段上都会得到一个警告。例如:字段“FileReader.Tests.CsvReader.Record.Field1”从未分配给,并且其默认值始终为0 事实上,我正在使用SetValueDirect()设置值,当我运行测试或调试代码时,我可以验证这一点。为什么它会给我这个错误,我怎样才能避免或修复它 下面是一些基本代码,让您了解一些情况。我猜我没
public abstract class FileReader<TRecord> : IDisposable where TRecord : struct
{
public TRecord? ReadRecord()
{
List<string> fields;
string rawData;
this.recordNumber++;
while (this.ReadRecord(this.fieldTypeInfoList.Length, out fields, out rawData))
{
try
{
// Insert the current record number to the beginning of the field list
fields.Insert(0, this.recordNumber.ToString(CultureInfo.InvariantCulture));
// Convert each field to its correct type and set the value
TRecord record = new TRecord();
FieldTypeInfo fieldTypeInfo;
object fieldValue;
// Loop through each field
for (int i = 0; i < this.fieldTypeInfoList.Length; i++)
{
fieldTypeInfo = this.fieldTypeInfoList[i];
bool allowNull = fieldTypeInfo.AllowNull == null ? this.AllowNull : fieldTypeInfo.AllowNull.Value;
if (i >= fields.Count && !allowNull)
{
// There are no field values for the current field
throw new ParseException("Field is missing", this.RecordNumber, fieldTypeInfo, rawData);
}
else
{
// Trim the field value
bool trimSpaces = fieldTypeInfo.TrimSpaces == null ? this.TrimSpaces : fieldTypeInfo.TrimSpaces.Value;
if (trimSpaces)
{
fields[i] = fields[i].Trim();
}
if (fields[i].Length == 0 && !allowNull)
{
throw new ParseException("Field is null", this.RecordNumber, fieldTypeInfo, rawData);
}
try
{
fieldValue = fieldTypeInfo.TypeConverter.ConvertFromString(fields[i]);
}
catch (Exception ex)
{
throw new ParseException("Could not convert field value", ex, this.RecordNumber, fieldTypeInfo, rawData);
}
fieldTypeInfo.FieldInfo.SetValueDirect(__makeref(record), fieldValue);
}
}
return record;
}
catch (ParseException ex)
{
ParseErrorAction action = (ex.FieldTypeInfo.ParseError == null) ? DefaultParseErrorAction : ex.FieldTypeInfo.ParseError.Value;
switch (action)
{
case ParseErrorAction.SkipRecord:
continue;
case ParseErrorAction.ThrowException:
throw;
case ParseErrorAction.RaiseEvent:
throw new NotImplementedException("Events are not yet available", ex);
default:
throw new NotImplementedException("Unknown ParseErrorAction", ex);
}
}
}
return null;
}
}
公共抽象类FileReader:IDisposable其中TRecord:struct
{
公共TRecord?ReadRecord()
{
列表字段;
字符串原始数据;
这个.recordNumber++;
while(this.ReadRecord(this.fieldTypeInfoList.Length,out fields,out rawData))
{
尝试
{
//将当前记录编号插入字段列表的开头
插入(0,this.recordNumber.ToString(CultureInfo.InvariantCulture));
//将每个字段转换为正确的类型并设置值
TRecord记录=新的TRecord();
FieldTypeInfo FieldTypeInfo;
对象字段值;
//循环遍历每个字段
for(int i=0;i=fields.Count&&!allowNull)
{
//当前字段没有字段值
抛出新的ParseException(“字段丢失”,this.RecordNumber,fieldTypeInfo,rawData);
}
其他的
{
//修剪字段值
bool trimSpaces=fieldTypeInfo.trimSpaces==null?this.trimSpaces:fieldTypeInfo.trimSpaces.Value;
如果(修剪空间)
{
字段[i]=字段[i].Trim();
}
if(字段[i].Length==0&&!allowNull)
{
抛出新的ParseException(“字段为空”,this.RecordNumber,fieldTypeInfo,rawData);
}
尝试
{
fieldValue=fieldTypeInfo.TypeConverter.ConvertFromString(字段[i]);
}
捕获(例外情况除外)
{
抛出新的ParseException(“无法转换字段值”,例如,this.RecordNumber、fieldTypeInfo、rawData);
}
fieldTypeInfo.FieldInfo.SetValueDirect(_makeref(记录),fieldValue);
}
}
返回记录;
}
捕获(解析异常)
{
ParseErrorAction动作=(ex.FieldTypeInfo.ParseError==null)?DefaultParseErrorAction:ex.FieldTypeInfo.ParseError.Value;
开关(动作)
{
案例ParseErrorAction.SkipRecard:
持续
案例ParseErrorAction.ThroweException:
投
案例ParseErrorAction.RaiseEvent:
抛出新的NotImplementedException(“事件尚不可用”,例如);
违约:
抛出新的NotImplementedException(“未知的ParseErrorAction”,ex);
}
}
}
返回null;
}
}
编译器似乎无法检测此类“间接”赋值。它只能检测直接赋值,如field=value
您仍然可以禁用特定的编译器警告。假设您使用的是Visual Studio,请参见此处:编译器永远无法发现反射。根据定义,通过使用反射,您已经走出了编译器
不过,在我看来,这是对结构的一个糟糕的使用——看起来它应该在类上工作……我讨厌重新发明轮子。来自的FileHelper已经以非常类似的方式完成了这项工作,当然还涵盖了更多的边缘案例。他们让你用属性而不是结构来定义一个类(正如Marc所建议的)。如果将它们的记录定义设置为非公共,则会得到与我相同的编译器警告。如果使用struct而不是class,您应该知道为什么要这样做 在某些(罕见)情况下,您应该使用struct:
--hfrmobile简化您的示例可能会更容易…我开始这样做,但后来它似乎过于简化了。我认为最重要的部分是:fieldTypeInfo.FieldInfo.SetValueDirect(u makeref(记录),field