resharper协变阵列转换 - 矛盾修复

时间:2016-12-07 12:37:07

标签: c# arrays resharper warnings

我有以下代码:

private static DataTable MyMethod(DataTable oneColDataTable)
{
   DataTable result = new DataTable();

   foreach (DataRow row in oneColDataTable.Rows)
   {
       string[] newRow = row[0].ToString().Split(';'); // [1] Co-variant array conversion when object[]

       while (newRow.Length > result.Columns.Count)
       {
           result.Columns.Add(new DataColumn());
       }

       result.Rows.Add(newRow); // [2] Co-variant array conversion                
   }

   return result;
}

此代码的功能

我在这里做的是使用一列DataTable。在那个专栏中,我有多行的内容:"这个;是;第一个;行" - "这个;是;另一个;行;那个;有;更多;单词&#34 ;; 我将此信息拆分为然后将单词解释为该行的列值。基本上将它转换为具有多行的表,如下所示:

Content of my DataTable:
|This|Is|the    |first|row |   |    |     |
|This|Is|another|row  |that|has|more|words|

共变阵列转换 - 问题

ReSharper警告我关于" Co-variant数组转换"在评论[2]。 resharper的自动修复功能可以转换" string []"在评论[1]到"对象[]"的行中。但现在它给了我相同的警告线[1]。自动修复会产生之前的代码,因此它基本上是一个非常烦人的循环。

我不想通过评论禁用警告,因为我通常认为这是一种懒惰和糟糕的方法。但我没有看到任何其他方法来解决这个问题。我在代码中做错了吗?有没有办法解决这个问题而不会抑制或忽略警告?

1 个答案:

答案 0 :(得分:3)

如果您的目标是删除该警告消息,则足以更改第一行以生成对象数组而不是字符串。

object[] newRow = row[0].ToString().Split(';').Cast<object>().ToArray();

但接下来的问题是,在枚举它所谓的新行时是否真的有必要设计表的结构,甚至是否为了消除消息而进行的这种改变可能会花费你在Cast<>和枚举上花费的一些性能

编辑: 问题是没有真正的问题需要解决。您收到警告说可能会发生。同样很高兴认识到R#警告并不意味着它肯定是错误的,它让你知道你应该关心那个部分。

想象:

public static object[] GetTuples()
{
    return new Tuple<string, int>[10]; // R# warning here
}
public static void Test()
{
    object[] tuples = GetTuples();
    tuples[0] = new Tuple<string, int>("", 1);
    tuples[1] = ""; // this will crash process, but no R# Warnings here
}

与您描述的情景相比:

string[] parts = "some;string".Split(",");
table.Rows.Add(parts);

R#没有权力区分这两种情况。你得到的警告在数学上是完全正确的。另一方面,作为开发人员,您知道它不会导致问题此警告是针对性的,因为您知道代码比R#更好。很高兴采纳你是你的代码的主,并且R#只是提示的有用来源 - 反之亦然。

完全正常的企业代码包含R#抑制,在开发人员知道它是安全的地方,同时愿意在代码库的其他部分启用它。

作为第二次编辑: 我发布的代码实际上并不隐藏任何(甚至是虚拟的)问题。它改变了从“类型系统的角度”发生的事情,虽然它可能听起来几乎相同,它有点“大不同”: 最初你创建了字符串[] - 例如一些能够存储字符串的实体 然后你已经将这个数组传递给了期望object[]的方法,并对此做了一些事情。这意味着会发生从string[]object[]的投射。在程序字中它意味着我给你对象[],你可以在那里存储任何System.object(例如从那里继承的所有东西),但正如所解释的那样,它不是真的。

鉴于事实我们知道发生了什么,我们知道它没关系(你可以在这里查看DataTable.cs:https://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs 并且确保在Add(object[] params))没有像前面提到的那样修改输入数组时没有问题 - 但是R#不知道这条信息。

在我改变之后你不再做那个演员了。您正在获取字符串数组,并逐个转换为对象,您正在创建全新的数组 - 而不仅仅是您之前数组的不同类型标识。希望这有助于而不是混淆。

顺便说一下。另一个正确的解决方案是禁用此类警告,但这不是最佳方式:)