指定的类型转换无效 - 将双精度列表转换为单精度列表

3

我在一个JSON文件中存储了一组浮点数,以下是JSON列表的样式:

"RollSize": "[17.5,18.0,19.0,23.5,26.5,35.0,35.5,38.0]"

我使用的是一个返回对象列表的方法,因为有多个列表需要返回。然后我将对象列表转换成浮点数。但是当这样做时,会收到一个“指定的转换无效”异常。但是如果我将对象列表转换为双精度,则可以正常工作。以下是两种方法:

private void DisplayCutOffs(object sender, EventArgs e) {
            try {
// Errors here unless I cast to double 
                _view.CurrentCutOffValues = _systemVariablesManager.ReturnListBoxValues("CutOff").Cast<float>().ToList();
            }
            catch (Exception ex) {
                LogErrorToView(this, new ErrorEventArgs(ex.Message));
            }
        }

存储库方法:

 public List<object> ReturnListBoxValues(string propertyName) {
            if (File.Exists(expectedFilePath)) {
                var currentJsonInFile = JObject.Parse(File.ReadAllText(expectedFilePath));
                return JsonConvert.DeserializeObject<List<object>>(currentJsonInFile["SystemVariables"][propertyName].ToString());
            }
            else {
                throw new Exception("Setup file not located. Please run the Inital Set up application. Please ask Andrew for more information.");
            }
        }

然而我注意到,如果我在foreach循环中循环列表,我可以将每个值转换为浮点数。所以我不确定这里发生了什么。
有人知道吗?

"[17.5,18.0,19.0,23.5,26.5,35.0,35.5,38.0]" 这是一个字符串而不是数组。 - hardkoded
你是对的,但它会解析成一个对象列表。 - Andrew
一个 double 是 8 字节,而 float 是 4 字节。Linq 通常会生成一个通用的列表对象,可以转换为任何类型,但不会将一个类型强制转换为另一个类型,除非是显式的。 - jdweng
@jdweng 那么我的转换是隐式的吗? - Andrew
是的。您正在使用.ToList(),它将Linq集合转换为List<object>。 - jdweng
1个回答

4
听起来你的代码正在将 object 强制转换为 (the type),其中 (the type) 可以是 floatdouble。这是一个拆箱操作,必须做到 正确的类型。作为 object,该值 知道它是什么 - 如果您错误地对其进行拆箱,则会抛出此异常(注意:如果您将其拆箱为大小和兼容的某些内容,则有一些灵活性 - 例如,您可以将 int-enum 拆箱为 int 和反之亦然)。
选项:
  • 保持 object,但要了解数据并正确拆箱 - 可能在拆箱后进行强制转换,即 float f = (float)(double)obj;(这里的 (double) 是从 objectdouble 的拆箱;(float) 是从 doublefloat 的类型转换)
  • 测试对象类型 / 使用 Convert.ToSingle
  • 将属性更改为首先定义的类型,而不是 object
完整示例:
List<object> actuallyDoubles = new List<object>{ 1.0, 2.0, 3.0 };
List<double> doubleDirect = actuallyDoubles.ConvertAll(x => (double)x); // works
// List<float> floatDirect = actuallyDoubles.ConvertAll(x => (float)x); // fails per question
List<float> floatViaDouble = actuallyDoubles.ConvertAll(x => (float)(double)x); // works
List<float> floatViaConvert = actuallyDoubles.ConvertAll(x => Convert.ToSingle(x)); // works

1
@Andrew 我在下面添加了一些进一步的例子。 - Marc Gravell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接