2016-12-07 5 views
1

私は、次のコードを持っている:ReSharperの共変配列変換 - 矛盾修正

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; 
} 

を私はここに何このコードの機能

は1列でのDataTableを取ることです。そのコラムでは、私はこのような内容を複数の行に持っています: "これは、最初の行" - "これは、もう一つは行です、それはあります。 この情報を分割して、単語をその行の列値として解釈します。 - 問題が

ReSharperのコメントで、「共同バリアント配列変換」について私に警告している[2

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

共同バリアント配列変換:基本的にはこのように、複数の行を持つテーブルにそれを変換します]。 resharperのAuto-Fixは、コメント行[1]の "string []"を "object []"に変えます。しかし今、それは私にコメント行のための同じ警告を与える[1]。これを自動修正すると、これまでのコードと同じ結果になるので、基本的には非常に厄介なループになります。

私は一般的には怠け者で悪いアプローチだと思っています。しかし、私はこれを修正する他の方法を参照してください。私のコードで何か間違っていますか?警告を無視したり無視したりせずにこれを修正する方法はありますか?

+1

実際にはそうです。 Splitは文字列を返しますが、Rows.Addはオブジェクトの配列だけを受け入れます。 –

+0

私は最新のR#Ultimateでこれを見ています。あなたがSmogenによって記述されているような場合には、あなたは実際にメッセージを受け取ります。どのバージョンのテストをしているのかわからない –

+1

@HimBromBeereテキストを読む必要があります。 2つ目の修正は、最初の型の型を 'object []'に変更します。 – juharr

答えて

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#は、この2つの場合を区別する力を持っていません。あなたが得ている警告は、完全に数学的に正しいものです。一方、開発者としては、R#よりも優れたコードがあることがわかっているため、この警告が対象とする問題を引き起こすことはありません。あなたはあなたのコードの主であり、R#はヒントの役に立つソースであるというアイデアを採用することは良いことです。その逆もありません。

これはまったく正常なエンタープライズコードですが、開発者がコードベースの他の部分で有効にしても安全だと知っている場所ではR#抑制が含まれています。

第2の編集: 私が投稿したコードは実際には(仮想でさえも)問題を隠すわけではありません。'Type system point of view'から起こっている事柄を変えますが、それはちょっとした違いがあるかもしれません。 元々あなたは文字列[]を作成しました。文字列を格納できるエンティティ 次に、この配列をobject[]が必要なメソッドに渡して、それを使って何かを行います。つまり、string[]からobject[]へのキャストが行われます。プログラムの言葉では、私はあなたにオブジェクト[]を与えていることを意味します。あなたはそこにSystem.objectを格納することができます(例えば、それから継承されたすべて)。 - しかし、R#はないhttps://referencesource.microsoft.com/#System.Data/System/Data/DataTable.cs をし、前に述べたようにAdd(object[] params))は、入力配列を変更しない間は問題は存在しません確認してください。

は、我々はあなたがここにDataTable.csを確認することができます(それはOKだ知っているが、何が起こるかを知っているという事実を考えます

私の変更後、もうキャストはしません。文字列を配列し、オブジェクトごとに1つずつキャストして、新しい配列全体を作成しています - 異なるタイプあなたの前の配列のアイデンティティ。混乱するよりもむしろ助けてくれることを願っています。

Btw。別の適切な解決策は、この種の警告を無効にすることですが、それは最善の方法ではありません:)

+1

ああ、Juharrsのコメントで私はそれを得た。 – HimBromBeere

+0

悲しいことに、私が行っていたことではありません。技術的にはコメントがなくても、これは基本的に同じですが、警告を抑制するもう1つの方法:問題を隠してしまいましたが、修正できませんでした。 あなたの答えをありがとう! – Smogen

+0

はい、今私は理解しています。あなたが正しいです。私はちょうどあなたがそれをあなたがやったように置くので、私はそれを扱うための適切な方法であると感じているので、私はコメントでそれを抑圧するだろうと思う。結局のところ、あなたが言ったように、私がしていることをするのは間違っていません。ありがとうございました! – Smogen