1

私のコードでは、次のように global.asax にルートを登録しました。

void RegisterRoutes(RouteCollection routes)
{
   routes.MapPageRoute(
    "product",
    "product/{id}",
    "~/index.aspx"
);

次に、index.aspx ページで、{id} 値が整数かどうかをテストします。

if (Page.RouteData.Values["id"] as int? != null)   
//always evaluate as null even id is an integer in the URL, ex: /product/1

同じ目標を達成するために他の方法 ( int.TryParse やthisなど) を使用できることは理解していますが、この場合、「as」を使用する意味はありますか?

4

5 に答える 5

5

進むべき道は、 に実際に格納されているものによって異なりますValues["id"]。実際に である場合は、 でテストintできます。プロパティはオブジェクトとして型付けされます。したがって、それは可能です。しかし、これは、保存された が. (以下の私の更新を参照してください。)intValues["id"] is intValues[]nullintNullable<int>

int(および他のすべての非参照型) をオブジェクト変数またはプロパティに割り当てると、ボックス化されます。つまり、対応する型のオブジェクトにパックされます。intまたはSystem.Int32、値型およびボックス化された不変のSystem.Int32参照型として存在します。その不変性により、参照型であることに気付きません。でボックス化およびボックス化解除intできます。object obj = 5;int i = (int)obj;

一方、ID が文字列として格納されている場合は、数値に変換する必要があります。

int id;
if (Int32.TryParse((string)Page.RouteData.Values["id"], out id)) {
    // use id here
}

アップデート:

nullとには混乱があるようNullable<T>です。

int? i; // Same as Nullable<int> or Nullable<System.Int32> or System.Int32?
object obj;
bool test;

i = null;
test = i.HasValue; // ==> false
test = i == null;  // ==> true

// Now comes the strange part

obj = 5;           // The int is boxed here.
// Debugger shows type of obj as "object {int}"
test = obj is int;   // ==> true
test = obj is int?;   // ==> true
int x = (int)obj;  // ==> 5, the int is unboxed here.

// But

obj = null;
// Debugger shows type of obj as "object"
test = obj is int; // ==> false
test = obj is int?; // ==> false
test = obj == null; // ==> true

// And
i = 5;
obj = i; // i is a Nullable<int>
// Debugger shows type of obj as "object {int}"
test = obj is int; // ==> true
test = obj is int?; // ==> true
test = obj == null; // ==> false

i = null;
obj = i;
// Debugger shows type of obj as "object"
test = obj is int; // ==> false
test = obj is int?; // ==> false
test = obj == null; // ==> true

と はどちらも数値を含む場合obj is intobj is int?返しますが、 !を含む場合は両方とも false を返します。Aはに割り当てられたときに に変換され、もはやではありません。trueobjintobjnullnull Nullable<int>(object)nullobjNullable<int>

デバッガーは、が割り当てられているかどうかに関係なく、数値が格納されている場合のobjように のタイプを表示します! の型はいつ格納されるかです。object {int}intint?objobjectnull

したがって、Cheong Le は実際に正しいのです。

于 2012-10-03T15:07:20.430 に答える
3

値は文字列になる可能性が高いため、を使用することをお勧めしますInt.TryParseInt.Parse例外も処理する必要があり、通常、例外をスローする可能性のあるものをコーディングすることは避けたいため、を使用しないでください(処理している場合でも)。

null許容型を使用する必要があるため、使用asすることは実際には良い解決策ではありませんintisルートを選択すると、渡された値がタイプの場合は機能しないことがほぼ保証されます。string

討論に関してis、私はこれをVSで実行しました:

string value = "42";
object answerToUniverse = value;
if (answerToUniverse is int)
{
    Console.WriteLine("It's an integer!");
}
else
{
    Console.WriteLine("It's NOT an integer!");
}

結果は次のとおりです。整数ではありません。

于 2012-10-03T15:00:21.787 に答える
0

おそらくあなたは実際にこれをしたいのでしょう、

var idString = Page.RouteData.Values["id"] as string;
int id;
if (int.TryParse(idString, out id))
{
   // id is now a valid number 
}
else
{
   // your types are confused
}
于 2012-10-03T15:00:59.903 に答える
0

タイプではなくをチェックしたいようです。つまり、タイプが何であるかはあまり気にしないということです。

そのような場合、これは私が推奨できる最善のアプローチです。

object idValue = Page.RouteData.Values["id"];
int dummy;
if (idValue != null && Int32.TryParse(idValue.ToString(), out dummy))
{
    //value is integer!
}

このように、タイプが何であるかは関係ありません。整数、double、文字列、または適切なToString()オーバーライドを使用した複合型の場合でも機能します。

于 2012-10-03T15:01:27.580 に答える
0

as安全なキャストです。null提供された値を目的の型にキャストしてキャストし、標準のキャストの場合に例外をスローする代わりに戻ります。

したがって、 Page.RouteData.Values["id"] が整数オブジェクトでない限り、これは機能せず、提案した代替メソッドを使用する必要があります。

1つは、拡張メソッドを使用することでした

public static class IntExtensions {
   public static int? AsInt(this string source) {
     int result;
     return (int.TryParse(source,out result)) ? (int?)null : result;
   }

   public static bool IsInt(this string source) {
     return source.AsInt.HasValue;
   }
}

あなたができるようにする

if (Page.RouteData.Values["id"].IsInt())
于 2012-10-03T15:02:08.637 に答える