【问题标题】:resharper covariant array conversion - contradicting fixresharper 协变数组转换 - 矛盾的修复
【发布时间】:2016-12-07 12:37:07
【问题描述】:

我有以下代码:

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。在该列中,我在多行中有这样的内容:“This;Is;the;first;row” - “This;Is;another;row;that;has;more;words”; 我拆分此信息,然后将单词解释为该行的列值。基本上将其转换为具有多行的表,如下所示:

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

协变数组转换 - 问题

ReSharper 在评论 [2] 中警告我“协变数组转换”。 resharper 的 Auto-Fix 将注释 [1] 行中的“string[]”变为“object[]”。但现在它给了我同样的评论行警告[1]。自动修复这会导致它之前的代码,所以它基本上是一个非常烦人的循环。

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

【问题讨论】:

  • 确实如此。当 Rows.Add 只接受对象数组时,Split 返回字符串。
  • 我现在正在使用最新的 R# Ultimate 进行处理,如果您按照 Smogen 的描述进行操作,您确实会收到上述消息。不确定您正在使用哪个版本进行测试。
  • @HimBromBeere 你必须阅读文本。第二个的修复将第一个的类型更改为object[]。

标签: c# arrays resharper warnings


【解决方案1】:

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

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

但是接下来的问题是,在枚举它应该是新行的过程中是否真的有必要设计表的结构,或者甚至为了摆脱消息而进行的这种更改是否会花费您在 Cast&lt;&gt; 和枚举上花费的一些性能

编辑: 问题是没有真正的问题需要解决。您会收到警告说可能会发生。意识到 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# 抑制。

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

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

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

顺便说一句。另一种正确的解决方案是禁用这种警告,但这不是最好的方法:)

【讨论】:

  • 啊,有了 Juharrs 的评论,我明白了。
  • 遗憾的是,这不是我想要的。它只是抑制警告的另一种方式,即使它在技术上没有评论但对我来说这基本上是相同的:我隐藏了问题,我没有解决它。不过感谢您的回答!
  • 是的,现在我明白了。你说的对。我想我会用评论来压制它,因为既然你按照你的方式表达,那就是我觉得处理它的正确方法。毕竟,正如你所说,做我所做的事情并没有“错误”。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-12-31
  • 2018-12-26
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 2017-11-06
  • 2016-02-21
相关资源
最近更新 更多