5

这与我的Are there any project templates for using T4 to generate classes有关吗?问题。我有需要为其生成正确类型的类属性的字符串 ( nvarchar) 参数值列表。

DateTime这些值是集合 { int, double, bool, DateTime}中的所有基元 - 最复杂的存在。目前,我已经为这样的列表之一手动编码类型属性,并解析我以DateTime.TryParseExact. 如果失败,我会尝试Double.TryParse,在底部我放弃猜测并假设它确实是一个字符串。

这是一种相当合理的方法,还是我应该使用其他更复杂或更准确的方法?

4

2 回答 2

3

If the set of values was only [double, DateTime, bool] this would be an exhaustive but fairly sound method. There is simply so overlap between those sets (true is always a bool and 5 is never a bool).

Having both int and double makes this proposition a bit flaky because there is a large amount of overlap. Essentially any int can be also seen as a double. How am I to interpret for example 4 if it appears in the value set? It could be interpreted both ways and if values change over time you could see the type of your generated code changing as well.

Consider if a column always had whole numbers simply by coincidence. Hence you generated int value and wrote a bit of code that depended on them being int. Then a month or so later a non-whole number was added and suddenly you are spitting out double values. This would probably have a non-trivial affect on your code.

Personally the approach I would take is to simply have another table which dictated the type of the contents.

于 2013-08-21T14:40:40.877 回答
2

看看Convert.ChangeTypeTypeDescriptor.GetConverter

我已经为我编写了一个扩展方法来做到这一点:

public static T Convert<T>(this object obj)
{
  T result;
  try
  {
    result = (T)System.Convert.ChangeType(obj, typeof(T));

    if (object.ReferenceEquals(result, null))
    {
      var typeConverter = !obj.IsNullable()
        ? TypeDescriptor.GetConverter(typeof(T))
        : new NullableConverter(typeof(T));

      result = obj is string
        ? (T)typeConverter.ConvertFromString(obj as string)
        : (T)typeConverter.ConvertTo(obj, typeof(T));
    }
  }
  catch (Exception)
  {
    result = default(T);
  }

  return result;
}

public static bool IsNullable<T>(this T obj)
{
  return Nullable.GetUnderlyingType(typeof(T)) != null;
}

用法:

var itemsToConvert = new[] { "4", "5.98", "false", DateTime.Now.ToString() };
var @int = itemsToConvert[0].Convert<int>();
var @double = itemsToConvert[1].Convert<double>();
var @bool = itemsToConvert[2].Convert<bool>();
var @dateTime = itemsToConvert[3].Convert<DateTime>();

Console.WriteLine(@"int: {0}, Type: {1}", @int, @int.GetType());
Console.WriteLine(@"double: {0}, Type: {1}", @double, @double.GetType());
Console.WriteLine(@"bool: {0}, Type: {1}", @bool, @bool.GetType());
Console.WriteLine(@"DateTime: {0}, Type: {1}", @dateTime, @dateTime.GetType());

输出:

int:4,类型:System.Int32
double:5.98,类型:System.Double
bool:False,类型:System.Boolean
DateTime:2013/08/21 06:01:07 PM,类型:System.DateTime

希望这可以帮助。

于 2013-08-21T16:04:05.780 回答