質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • C#

    7446questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C#「値を返さないコード パスがあります。」のエラー

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 7,826

Lark7

score 1

前提・実現したいこと

C#にて、対象文字列とワイルドカードを引数として渡したら
対象文字列がワイルドカードの条件に当てはまるかどうかをTrue or Falseを返すようなメソッドを
作りたいと考えています。

なお、ワイルドカードは「ABC*,DEF??,*GH」といったように複数の条件をカンマ区切りで
一度に指定できるようにしたいです。

例えば、ObjText="TestText"である場合
Wildcard="ABC,Te*"ならTrueを返し、Wildcard="Te*,ABC,"でもTrueを返すが
Wildcard="ABC,DE*"ならFalseを返すといった形です。

発生している問題・エラーメッセージ

CS0161    'Form1.test(string, string)': 値を返さないコード パスがあります。


下記のように記述したところ、上記のようなエラーが出てコンパイルできない状況です。

該当のソースコード

        public bool test(string ObjText, string Wildcard)
        {

            string[] stArrayData = Wildcard.Split(',');

                foreach (string stData in stArrayData)
                {
                   //ワイルドカードの文字列を正規表現の文字列に変換する
                    var regexPattern = Regex.Replace(stData, ".",
                      m =>
                      {
                          string s = m.Value;
                          if (s.Equals("?"))
                          {
                              //?は任意の1文字を示す正規表現(.)に変換
                              return ".";
                          }
                          else if (s.Equals("*"))
                          {
                              //*は0文字以上の任意の文字列を示す正規表現(.*)に変換
                              return ".*";
                          }
                          else
                          {
                              //上記以外はエスケープする
                              return Regex.Escape(s);
                          }
                      }
                      );

                    bool rg = new Regex(regexPattern).IsMatch(ObjText);
                    if (rg)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                } 
        }

試したこと

例外が起きた場合に if(rg)の中のreturn分を通らない場合があるのかもしれないと考え、
Try-Catchをいろいろな場所に記述してCatch内にreturnを入れてみたりしたのですが、エラーに変化はありませんでした。ワイルドカードを正規表現に変換するところの処理は正直あまり理解できておらず、見当違いなことをしているかもしれず恐縮なのですが、お知恵をお貸しいただければ幸いです。

補足情報(言語/FW/ツール等のバージョンなど)

C#を使ったワイルドカードの使用については、下記を参考にしました。
http://qiita.com/kazuhirox/items/5e314d5e7732041a3fe7

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

エラーとは関係ないですが、Wildcardの最初のやつしか判定しないスね。
自分だったら、ループ内では true のみ return し
ループの外(全部ハズレだった場合) false を return する
って形にするかなあ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/11 22:00

    おっしゃる通りですね。。。
    ご指摘通り修正したらうまくいきました。
    煮詰まっていたので大変助かりました!ありがとうございました。

    キャンセル

+1

public int Test(int[] xs){
    foreach(var x in xs){
        return 1;
    }
}

これは一見、すべてのパスで値を返しそうですが、
xsが空の場合はforeach内に入らないのでパス無しになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/11 22:11

    なるほど。。
    当方のコードの問題はforeach内に入らないという抜け道があったのですね。
    どんな場合でも一度はforeach内に入る前提でいろいろとトライしてしまっていました。
    takasima20さんのご回答と合わせて、foreach外にreturn falseを記述する意味を改めて納得いたしました。
    ありがとうございました。

    キャンセル

0

メソッドの分割に慣れていないようですね。
ワイルドカードを正規表現クラスに返還するメソッドを加えてみました。

public bool test(string text, string wildcards){
    foreach(string wildcard in wildcards.Split(',')){
        var reg = ConvertWildcardToReges(wildcard);
        if(reg.IsMatch(ObjText)){
            return True;
        } else {
            return False;
        }
    }
}

private Regrex ConvertWildcardToReges(string wildcard){
    //ワイルドカードの文字列を正規表現の文字列に変換する 
    var regexPattern = Regex.Replace(wildcard, ".", 
        m => { 
            string s = m.Value; 
            if (s.Equals("?")) { 
               //?は任意の1文字を示す正規表現(.)に変換 
               return "."; 
            } else if (s.Equals("*")) { 
               //*は0文字以上の任意の文字列を示す正規表現(.*)に変換 
               return ".*"; 
            } else { 
               //上記以外はエスケープする 
               return Regex.Escape(s); 
            } 
       });

       retrun new Regex(regexPattern).IsMatch(ObjText); 
}


ちなみにこのコードはエラーが残ったままです。(バグを新しく作りこんでしまったかもしれません。)

testメソッドがずいぶんスッキリしていることに同意してもらえるはずです。
このコードを見て、エラーの原因に気づいてもらえたらよいのですが・・・

さらにヒントを続けます。

var ret = test("TestTest", "");


このretの値はTrueでしょうかFalseでしょうか。
おそらく、変更前のコードではわかりづらかったかもしれませんが、このコードで考えるとすぐわかると思います。

短いメソッドのほうがエラーは見つけやすいので、上手にメソッドの分割をしたほうが良いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/11 22:42

    コメントありがとうございます。
    >メソッドの分割に慣れていないようですね。
    おっしゃる通り、我流でVBAを触ってきて、C#はここ最近始めたばかりでして、なんとかコンパイル通るようにするのが精いっぱいという状況でお恥ずかしい限りです。
    (メソッドの分割流儀などはVBAでもC#でもそれほど違いがある話もないと思うので言い訳にもなりませんが。。。)
    前にコメントいただいたozwkさんのご指摘からすると
    wildcardsがnullの場合のパスなしで、ご提案いただいたコードでもtestメソッドはコンパイル通らないかなぁと考えました。
    下記はまさにwildcardsがnullの例、ということですかね?
    var ret = test("TestTest", "");

    キャンセル

  • 2016/05/11 23:51

    nullではないです。

    長さ0の文字です。Nullと0の差は説明しずらいですが、test("TestTest", null)は呼び出し側でエラーになります。

    wildcardをSplitしたときに長さ0の配列が返ってくるので、foreachの中の処理は実行されず。値が帰らないまま処理が抜けます。

    foreach構文のあとにreturn False;を入れるというのが答えになります。

    ループや条件式が複雑になるとこの手モレが発生しやすくなります。一目でわかる大きさにメソッドを分割するように心がけてください。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    計算機のプログラム

    初めて質問投稿します。質問に対して不足している情報などあるかもしれませんが、ご容赦ください。 Javaで簡単な計算機の仕組みを作ろうとしています。 しかし、いざコンパイルしようと

  • 解決済

    java 電卓プログラム

    前回から少しだけ前進しましたが、まだ壁にぶつかっているのでご助力お願いいたします。 表記イメージとしては、実行するとまずは下記が表示されます。  C\JAVA>java D

  • 解決済

    Javaでの入力チェックのif文を減らしたい。

    Javaを使った簡単なプログラムを作っています。 開始 適当な文字列その1を入力してエンターキー(3文字以上10文字以下、半角数字、半角大小英字のみ) 1.1 不正

  • 解決済

    アップルスクリプトで行頭・行末のスペース・タブを削除する

    アップルスクリプト単体での文字操作はしづらいということで、 Perlを使用して文字置き換えを試みています。 ですが、正規表現"^ +"がうまく機能せず、 処理結果は、元の文字

  • 解決済

    JSPでtextboxに入力されていない場合を判定するには

    JSPを使用し、新しい商品を登録するプログラムを作成しています。 商品名や単価などを入力するtextboxを作り、そのなかで空欄が一つでもある場合には、「エラー.html」に遷

  • 解決済

    MVC モデルのバリデーションについて

    モデルでアノテーション(Required)を指定しているプロパティが4つあります。 [Required] public string A { get; set;

  • 解決済

    C# HTMLタグを除去したい

    実現したいこと HTMLタグ(<!--~-->の中身/</a>・</span>・</b>)などの除去の仕方がわかりません。どう処理したらいいのでしょうか。取得はHTML Agili

  • 解決済

    equals()のtrue, falseの判定

     equals()のtrue, falseの判定 Java初心者です。equals()で以下のコードで文字列を比較しているのですが、実行結果が「first and second b

同じタグがついた質問を見る

  • C#

    7446questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。