8

と があり、stringそのに変換されTypeた値を返したい。stringType

public static object StringToType(string value, Type propertyType)
{
    return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture);
}

objectこれは、プロパティ セット値の呼び出しで使用できる を返します。

public static void SetBasicPropertyValueFromString(object target,
                                                   string propName,
                                                   string value)   
{
  PropertyInfo prop = target.GetType().GetProperty(propName);
  object converted = StringToType(value, prop.PropertyType);
  prop.SetValue(target, converted, null);
}

これは、nullable を除くほとんどの基本型で機能します。

[TestMethod]
public void IntTest()
{ //working
    Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int)));
    Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int)));
}

[TestMethod]
public void NullableIntTest()
{ //not working
    Assert.AreEqual(1, ValueHelper.StringToType("1", typeof (int?)));
    Assert.AreEqual(123, ValueHelper.StringToType("123", typeof (int?)));
    Assert.AreEqual(null, ValueHelper.StringToType(null, typeof (int?)));
}

NullableIntTest最初の行で失敗します:

System.InvalidCastException: 'System.String' から 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' へのキャストが無効です。

型が null 許容であるかどうかを判断し、StringToTypeメソッドの動作を変更するのが困難です。

私が求めている行動:

文字列が null または空の場合は null を返し、それ以外の場合は null 非許容型に従って変換します。

結果

キリルの答えのように、1回のChangeType呼び出しで。

public static object StringToType(string value, Type propertyType)
{
    var underlyingType = Nullable.GetUnderlyingType(propertyType);
    if (underlyingType != null)
    {
        //an underlying nullable type, so the type is nullable
        //apply logic for null or empty test
        if (String.IsNullOrEmpty(value)) return null;
    }
    return Convert.ChangeType(value,
                              underlyingType ?? propertyType,
                              CultureInfo.InvariantCulture);
}
4

6 に答える 6

6

IConvertible から継承されないため、null 許容型で Convert.ChangeType を使用することはできません。メソッドを書き直す必要があります。

public static object StringToType(string value, Type propertyType)
{
   var underlyingType = Nullable.GetUnderlyingType(propertyType);
   if(underlyingType == null)
          return Convert.ChangeType(value, propertyType,  CultureInfo.InvariantCulture);
   return String.IsNullOrEmpty(value)
          ? null
          : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture);
}
于 2012-11-14T15:18:59.433 に答える
3
public static object StringToType(string value, Type propertyType)
{
   var underlyingType = Nullable.GetUnderlyingType(propertyType);
   return underlyingType == null ? Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture) : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture);
}
于 2012-11-14T15:15:23.417 に答える
2

ここでの問題はChangeType、メソッドと同様に の戻り値が であるということですobject。null 許容型を にボックス化するobjectと、null 許容型はボックス化されません。実行時に値が実際に null の場合は をボックス化しnull、値がある場合は (null 許容バージョンではなく) 実際の基礎となる値をボックス化します。

int? i = 5;
object o = i;
Type t = o.GetType();//will be `int`, not `Nullable<int>`

これは、他のタイプの一般的なケースでは発生しません。Nullable<T>これを行うための特別なコンパイラ サポートがあります。基本的Nullableに、コードでも特殊なケースが必要になります。メソッドに型が渡されたNullable場合は、まずオブジェクトの をチェックする必要があります。nullそうでない場合は null、代わりに の基になる型を使用しNullableます。

于 2012-11-14T15:25:26.603 に答える
2

これを試して:

prop.IsGenericType && Nullable.GetUnderlyingType(prop) == value.GetType()
于 2012-11-14T15:11:01.117 に答える
1

Kirill Bestemyanov のスニペットを使用したコード:

public static object StringToType<T>(string value)
{
   return StringToType(value, typeof(T));
}

public static object StringToType(string value, Type propertyType)
{
   var underlyingType = Nullable.GetUnderlyingType(propertyType);
   if(underlyingType == null)
     return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture);
   return String.IsNullOrEmpty(value)
     ? null
     : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture);
}

そして使用法(WLコンソールに書き込むだけです)。int?おっしゃる通り、ジェネリック メソッドはジェネリック パラメーターとして使用できません。

WL(StringToType("1", typeof (int?))); // -> 1
WL(StringToType<int>("1"));           // -> 1
WL(StringToType<int?>("1"));          // error, not compilable
WL(StringToType<Nullable<int>>("1")); // -> 1
于 2012-11-14T16:24:40.237 に答える
0

サポートするタイプごとに適切なキャスト方法を使用する必要があります。

int parsedInt;
int.TryParse("1", out parsedInt);

double parsedDouble;
double.TryParse("0.0d", out parsedDouble);

文字列の内容によっては、コンパイラが型を判別することはできません。文字列からスカラータイプへの変換の詳細については、次のリンクを参照してください:http: //msdn.microsoft.com/en-us/library/bb397679.aspxおよびhttp://msdn.microsoft.com/en-us/library /bb384043.aspx

于 2012-11-14T15:17:18.577 に答える