[英]c# struct fields are “never assigned to” warnings
Based on http://alexreg.wordpress.com/2009/05/03/strongly-typed-csv-reader-in-c/ , I created a DLL which can read different file types. 基于http://alexreg.wordpress.com/2009/05/03/strongly-typed-csv-reader-in-c/ ,我创建了一个可以读取不同文件类型的DLL。 I also have unit tests that run successfully.
我也有成功运行的单元测试。 I create a struct and use it as the generic type.
我创建一个结构并将其用作泛型类型。
Anyway, when I compile, I get a warning on each of the struct fields. 无论如何,当我进行编译时,我会在每个struct字段上得到一个警告。 For example: field 'FileReader.Tests.CsvReader.Record.Field1' is never assigned to, and will always have its default value 0
例如:字段'FileReader.Tests.CsvReader.Record.Field1'从未分配给它,并且将始终具有其默认值0
I am in fact setting the value with SetValueDirect() and when I run through the tests or debug the code, I can verify that. 实际上,我是通过SetValueDirect()设置值的,当我运行测试或调试代码时,我可以进行验证。 Why is it giving me that error then, and how can I avoid or fix it?
为什么它会给我该错误,以及如何避免或解决该错误?
Here is some basic code to give you an idea. 这是一些基本的代码可以给您一个想法。 I'm guessing I haven't provided enough, but hopefully someone has a clue.
我猜我还没有提供足够的信息,但希望有人能提供一些线索。
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;
}
}
The compiler is never going to be able to spot reflection. 编译器永远无法发现反射。 By definition, by using reflection you have stepped outside the compiler.
根据定义,通过使用反射,您已走出编译器。
IMO, though, this is a bad use of structs - that looks very much like it should be working on classes... IMO,但是,这是对结构的错误使用-看起来非常像它应该在类上工作...
It seems that the compiler is not capable of detecting such "indirect" assignments. 似乎编译器无法检测到这种“间接”分配。 It can only detect direct assignments like
field=value
. 它只能检测直接分配,例如
field=value
。
You can anyway disable specific compiler warnings. 您仍然可以禁用特定的编译器警告。 Assuming that you are using Visual Studio, see here: http://msdn.microsoft.com/en-us/library/edzzzth4.aspx
假设您使用的是Visual Studio,请参见此处: http : //msdn.microsoft.com/zh-cn/library/edzzzth4.aspx
If using struct instead of class you should know why you do it. 如果使用struct而不是class,您应该知道为什么这么做。
Some (rare) cases where you should use struct: 在某些(罕见)情况下,应使用struct:
--hfrmobile --hfrmobile
I hate when I reinvent the wheel. 我讨厌重新发明轮子。 FileHelpers from http://www.filehelpers.com/ already does this in a very similar way and of course covers more edge cases.
来自http://www.filehelpers.com/的 FileHelpers已经以非常相似的方式执行此操作,并且当然涵盖了更多的极端情况。 They have you define a class with attributes instead of a struct (as Marc suggested).
他们让您使用属性而不是结构来定义类(如Marc建议的那样)。 If you set their record definition as non-public, you get the same compiler warnings I was getting.
如果将其记录定义设置为非公开,则会收到与我相同的编译器警告。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.