Поля c # struct никогда не назначаются - PullRequest
2 голосов
/ 29 октября 2009

На основании http://alexreg.wordpress.com/2009/05/03/strongly-typed-csv-reader-in-c/, Я создал DLL, которая может читать файлы разных типов. У меня также есть модульные тесты, которые успешно выполняются. Я создаю структуру и использую ее как универсальный тип.

В любом случае, когда я компилирую, я получаю предупреждение о каждом из полей структуры. Например: поле «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;
        }
}

Ответы [ 4 ]

3 голосов
/ 29 октября 2009

Компилятор никогда не сможет определить отражение. По определению, используя отражение, вы вышли за пределы компилятора.

ИМО, однако, это плохое использование структур - похоже, что оно должно работать на классах ...

1 голос
/ 15 августа 2010

Если вы используете struct вместо class , вы должны знать, почему вы это делаете.

Некоторые (редкие) случаи, когда вы должны использовать struct:

  1. P / Invoke (когда нативная функция использует «Structs») - это (imho) одна из причин, по которой MS добавила struct в .NET (чтобы быть совместимой с нативным кодом)
  2. структуры - это так называемые типы значений. структуры должны быть очень маленькими (например, struct DateTime, struct GpsCoordinates являются причинами использования struct вместо классов, поскольку struct "быстрее", чем классы, поскольку GC не нужно заботиться об этом
  3. Если вы не знаете, что использовать: используйте класс !!

- hfrmobile

1 голос
/ 29 октября 2009

Похоже, что компилятор не способен обнаруживать такие "косвенные" назначения. Он может обнаруживать только прямые назначения, такие как field=value.

В любом случае вы можете отключить определенные предупреждения компилятора. Предполагая, что вы используете Visual Studio, смотрите здесь: http://msdn.microsoft.com/en-us/library/edzzzth4.aspx

0 голосов
/ 04 ноября 2009

Ненавижу, когда заново изобретаю колесо. FileHelpers из http://www.filehelpers.com/ уже делает это очень похожим образом и, конечно, покрывает больше крайних случаев. Они предлагают вам определить класс с атрибутами вместо структуры (как предложил Марк). Если вы установите их определение записи как непубличное, вы получите те же предупреждения компилятора, что и я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...