web-dev-qa-db-ja.com

型 'int?'を暗黙的に変換できません「int」に。

「暗黙的に型 'int?'を変換できません」というエラーが表示されます。 「int」に変換します。明示的な変換が存在します(キャストを見逃していますか?)」私のC#スキルはそれほど高度ではないので、なぜかわかりません。任意の助けをいただければ幸いです。

static int OrdersPerHour(string User)
{
    int? OrdersPerHour;
    OleDbConnection conn = new OleDbConnection(strAccessConn);
    DateTime curTime = DateTime.Now;        

    try
    {
        string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > #" + curTime.AddHours(-1) + "# AND User = '" + User + "' AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered');";
        OleDbCommand dbcommand = new OleDbCommand(query, conn);
        dbcommand.Connection.Open();
        dbcommand.CommandType = CommandType.Text;
        OrdersPerHour = (int?)dbcommand.ExecuteScalar();

        Console.WriteLine("Orders per hour for " + User + " is " + OrdersPerHour);            
    }
    catch (OleDbException ex)
    {

    }
    finally
    {
        conn.Close();
    }
    return OrdersPerHour;
}
18
MaylorTaylor

OrdersPerHourint?にキャストしています

OrdersPerHour = (int?)dbcommand.ExecuteScalar();

それでも、メソッドのシグネチャはintです:

static int OrdersPerHour(string User)

また、簡単な提案-> クエリでパラメータを使用、次のようなもの:

string query = "SELECT COUNT(ControlNumber) FROM Log WHERE DateChanged > ? AND User = ? AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered')";
OleDbCommand dbcommand = new OleDbCommand(query, conn);
dbcommand.Parameters.Add(curTime.AddHours(-1));
dbcommand.Parameters.Add(User);
14

これは、メソッドの戻り値の型がintであり、OrdersPerHourがintであるためです。 (nullable)、以下のような値を返すことでこれを解決できます:

return OrdersPerHour.Value

また、以下のような例外を回避するために、nullではないかどうかを確認します。

if(OrdersPerHour != null)
{

    return OrdersPerHour.Value;

}
else
{

  return 0; // depends on your choice

}

ただし、この場合、else部分またはif部分の後に他の値を返す必要があります。そうでない場合、コンパイラは、コードのすべてのパスが値を返すわけではないエラーにフラグを立てます。

11
tariq
Int32 OrdersPerHour = 0;
OrdersPerHour = Convert.ToInt32(dbcommand.ExecuteScalar());
6
FalloutBoy

最後の行を次のように変更できます(dbに何もないときに0を返したい場合):

return OrdersPerHour == null ? 0 : OrdersPerHour.Value;
1
loopedcode

コードで最初に発生する問題はメッセージです

ローカル変数OrdersPerHourは、アクセスする前に初期化されない場合があります。

これは、データベースクエリが例外をスローする場合に、値が何かに設定されていない可能性があるためです(空のcatch句があります)。

これを修正するには、クエリが失敗した場合に必要な値(おそらく0)に値を設定します。

int? OrdersPerHour = 0;

これが修正されると、今あなたが投稿しているエラーがあります。これは、メソッドシグネチャがintを返すことを宣言しているが、実際にはnullable int、int?、変数を返すために発生します。

したがって、int?int部分を取得するには、.Valueプロパティを使用できます。

return OrdersPerHour.Value;

ただし、開始時にOrdersPerHourを0ではなくnullと宣言した場合、値はnullになる可能性があるため、返される前に適切な検証が必要になる可能性があります(たとえば、より具体的な例外をスローします)。

そのためには、HasValueプロパティを使用して、値を返す前に値を持っていることを確認できます。

if (OrdersPerHour.HasValue){
    return OrdersPerHour.Value;
}
else{
    // Handle the case here
}

サイドノートとして、C#でコーディングしているので、C#の規則に従えばよいでしょう。パラメーターと変数は、PascalCaseではなくcamelCaseにある必要があります。したがって、UserOrdersPerHouruserordersPerHourになります。

1

可能なnull戻り値に関心がある場合は、次のようなものも実行できます。

_int ordersPerHour;  // can't be int? as it's different from method signature
// ... do stuff ... //
ordersPerHour = (dbcommand.ExecuteScalar() as int?).GetValueOrDefault();
_

このように、潜在的な予期しない結果に対処し、.GetValueOrDefault(-1)またはより意味のある何かを入力することにより、式にデフォルト値を提供することもできます。

1
Rubens Farias

OrdersPerHour = (int?)dbcommand.ExecuteScalar();

このステートメントは、OrdersPerHour = (int)dbcommand.ExecuteScalar();と入力する必要があります

1
Josh

シンプルな

(i == null) ? i.Value : 0;
0
HoQuocThinh

メソッドの戻り値の型はintであり、int?

0
cassiorgr