2012-02-28 13 views
2

私は単純な解析問題を解決しようとしており、選択肢のリストをエンコードするためにenumを使用することに決めました。総称して列挙型をキャストするにはどうすればよいですか?

入力データは、データが存在する一意のヘッダーと一意ではない識別子を持つブロックに分割されたストレートASCIIテキストです。私はかなりの一般的な象徴化メソッドを書くことができますが、データの意味については何の文脈も提供せず、返されるとそれを処理します。

これを文字列で行うことは問題ありません。私はちょうど私達が行くリストを渡します。

私は列挙型を一般化するための構文を理解することはできません。私はいくつかの助けをすることができます。私はまた、命令的思考に余りにも拘束され、これに対する簡単な答えが欠けている可能性があります。入力があるので、

は、ここで私は私が

private enum Colors { red, white, green }; 
private enum Suits { spades, clubs, hearts, diamonds }; 

// ... open files, read data, etc 
// so I pass in the enum that I want my result in and some text identifiers 

parseToEnum (Colors, searchBlock, "startColorBlock", "endColorBlock", "id="); 
parseToEnum (Suits, searchBlock, "startCardSuitsBlock", "endCardSuitsBlock", "<id="); 

// ... 

をやっているの

private void parseToEnums(Enum returnEnum, string searchBlock, string startIDText, 
          string endIDText, string startText, string endText) 
{ 
    string ourSearchBlock = searchBlock; 
    int endIDidx = ourSearchBlock.IndexOf(endIDText); 

    while (ourSearchBlock.IndexOf(startText) != -1) 
    { 
     if (ourSearchBlock.Length == searchBlock.Length) 
     { 
      // first pass, trim off the region where the start text isn't valid 
      ourSearchBlock = ourSearchBlock.Remove(endIDidx, ourSearchBlock.Length - endIDidx); 
      // first pass, use the startIDtext to create a valid search zone 
      // BROKEN CODE HERE 
      // Neither GetType() nor typeof seem to do the right thing 
      // I have tried several varieties and have tried casting the LHS in the 
      // same sort of way 
      // pluckText returns a string that is guaranteed to match an enum name 
      returnEnum = (returnEnum.GetType()) System.Enum.Parse(typeof(returnEnum), pluckText(ourSearchBlock, startIDText, startText, endText), false); 
      ourSearchBlock = ourSearchBlock.Remove(0, ourSearchBlock.IndexOf(startIDText) + startIDText.Length); 
     } 
     else 
     { 
      // this would be similar to the above after it's working 
      // and is for the case where the string has multiple matches 
      // within the enum, ie "red white" 
      //returnList.Add(pluckText(ourSearchBlock, "", startText, endText)); 
     } 
     ourSearchBlock = ourSearchBlock.Remove(0, ourSearchBlock.IndexOf(startText) + startText.Length); 
    } 

    return; 
} 

例で苦労しているコードは、だから、考え方は同じ構造を(使用することです同じですが)出力には異なる列挙型を使用します。

私は、あまりにも多くの時間の前に、このコードにtry/catchラッパーと一般的なエラー検出を追加する必要があることを認識しています。

答えて

9

私はそれらのすべての検索を無視し、stringenumに変換することに焦点を当てます。

まず、あなたのメソッドはを返します。結果は、パラメータとして渡されません(そのためにはoutが必要です)。

第2に、enumの型をメソッドに渡すには、型パラメータTypeのaパラメータを使用するか、またはメソッドを汎用型にして型引数として渡します。

方法は次のようになります。

T ParseEnum<T>(string s) 
{ 
    return (T)Enum.Parse(typeof(T), s, false); 
} 

あなたは、このようにそれを呼び出すことができます:あなたのコード内

Colors color = ParseEnum<Colors>(someString); 

エラーは以下のとおりです。

  • Enumが一般的ですベースタイプがすべてenumの場合、enumのタイプではありません。つまり、メソッドのパラメータとしてColorsを使用することはできません。
  • 実行時にのみ既知の型にキャストすることはできません。つまり、(foo.GetType())barのようなコードは決してうまくいかないでしょう。
  • typeof演算子を使用して変数の型を取得することはできません。これを使用して、特定のタイプのTypeオブジェクトを取得することができます。 typeof(string)またはtypeof(T)は、タイプ引数Tを持つ汎用メソッドにあります。
  • タイプの名前(enumを含む)は、単数である必要があります。これは、例えば、タイプColorの変数がとなり、の色を表すためです。これはスタイル上の問題に過ぎませんが、コードが機能しなくなることはありません。しかし、それはあなたのコードを理解しにくくするでしょう。
+0

私はそれを含めていない場合、誰かが十分な詳細を提供しなかったために私を爆破していたでしょう。私はこれが大好きで、それに渦をかけるでしょう。 – Stephen

+0

私もcolor&= Par ...と書くことができるのが好きです。この方法で。 – Stephen

+0

あなたはそれを書いていますが、おそらくあなたが望むように動作しません。同時にいくつかの値を表すことができる 'enum'を持たせたい場合は、重複しないバイナリ値(1,2,4,8など)に値を設定し、' | 'を使って結合しなければなりませんそれら。 – svick

関連する問題