web-dev-qa-db-ja.com

C#の大文字と小文字を切り替える-定数値が必要です

私のコードは次のとおりです。

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    switch (dataSourceName)
    {
        case (string)typeof(CustomerDetails).Name.ToString(); :
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}

しかし、これは機能していません。 caseステートメントは、定数変数が必要だというエラーを表示しています。みんな助けてくれてありがとう!

49
johnnie

C#switchステートメントの制限-なぜ? を参照してください

基本的に、スイッチはcaseステートメントに評価済みステートメントを含めることはできません。それらは静的に評価されなければなりません。

30
deepee1

Switchステートメントの定数にのみ一致できます。


例:

switch (variable1)
{
    case 1: // A hard-coded value
        // Code
        break;
    default:
        // Code
        break;
}

成功しました!


switch (variable1)
{
    case variable2:
        // Code
        break;
    default:
        // Code
        break;
}

CS015 定数値が必要です。

27

Case値は式として評価できないため、これにはswitchステートメントを使用できません。これには、if/elseを使用する必要があります...

_public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    if(string.Compare(dataSourceName, typeof(CustomerDetails).Name.ToString(), true)==0)
    {
        var t = 123;
    }
    else if (/*case 2 conditional*/)
    {
        //blah
    }
    else
    {
        //default case
        Console.WriteLine("Test");
    }
}
_

また、あなたの条件文を片付ける自由を取りました。 ToString()を呼び出した後に文字列にキャストする必要はありません。とにかく、これは常に文字列を返します。文字列が等しいかどうかを比較するときは、==演算子を使用すると大文字と小文字が区別される比較になることに留意してください。最後の引数で文字列比較= 0を使用して、大文字と小文字を区別するオン/オフを設定する方が良いでしょう。

8
iDevForFun

ジョニー、 switch のmsdnガイドをご覧ください。また、C#言語仕様では、コンパイル時のエラーケースが明確に定義されています。

•switch式のタイプがsbyte、byte、short、ushort、int、uint、long、ulong、bool、char、string、enum-typeの場合、またはこれらのタイプのいずれかに対応するNULL入力可能なタイプの場合、それがswitchステートメントの管理タイプです。

•それ以外の場合、switch式の型から次の可能な管理型のいずれかへのユーザー定義の暗黙的な変換(§6.4)が1つだけ存在する必要があります。sbyte、byte、short、ushort、int、uint、long、ulong、char、文字列、またはそれらの型のいずれかに対応するnull許容型。

•そうでない場合、そのような暗黙の変換が存在しないか、そのような暗黙の変換が複数存在する場合、コンパイル時エラーが発生します。

お役に立てれば。

3
AksharRoop

少なくとも私がVisual Studio 2017で試したとき、これは私にとってはうまくいくようです。

public static class Words
{
     public const string temp = "What";
     public const string temp2 = "the";
}
var i = "the";

switch (i)
{
  case Words.temp:
    break;
  case Words.temp2:
    break;
}
3
Korey

switchの値はコンパイル時定数でなければならないという意味で、switchは非常にうるさいです。また、比較される値はプリミティブ(または文字列)でなければなりません。このためには、ifステートメントを使用する必要があります。

理由は、Cがジャンプテーブルを作成するという点でCがそれらを処理する方法に戻る可能性があります(値はコンパイル時定数であるため)。

3
Jesus Ramos

これでnameofを使用できます:

_public static void Output<T>(IEnumerable<T> dataSource) where T : class
{
    string dataSourceName = typeof(T).Name;
    switch (dataSourceName)
    {
        case nameof(CustomerDetails):
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}
_

nameof(CustomerDetails)は基本的に文字列リテラル_"CustomerDetails"_と同じですが、コンパイル時のチェックで(入力ミスを防ぐため)何らかのシンボルを参照します。

nameofはC#6.0で登場したので、この質問が尋ねられた後。

1
0xF