【问题标题】:how to convert csharp 8 code to earlier version如何将 csharp 8 代码转换为早期版本
【发布时间】:2021-02-10 12:46:50
【问题描述】:

我需要更改此代码以在早期版本的 c# 上工作 在下面的代码中如何改变这样的条件

if (value is TimeSpan ts)

到更早的 c# ?

string parsedValue;
bool parsed;

if (value == DateTime d && d >= BaseDate)
{
    parsedValue = d.ToOADate().ToInvariantString();
    parsed = true;
    SetDateTimeFormat(style, d.Date == d);
}
else if (value is TimeSpan ts)
{
    parsedValue = ts.TotalDays.ToInvariantString();
    parsed = true;
    SetTimeSpanFormat(style);
}
else if (value is Boolean b)
{
    parsedValue = b ? "1" : "0";
    _dataType = XLDataType.Boolean;
    parsed = true;
}

同样在下面的代码中

private static Boolean TryGetBasicValue<T, U>(String currentValue, ParseFunction<U> parseFunction, out T value)
{
    if (parseFunction.Invoke(currentValue, NumberStyles.Any, null, out U result))
    {
        value = (T)Convert.ChangeType(result, typeof(T).GetUnderlyingType());
        return true;
    }

    value = default;
    return false;
}

如何更改 c# 7

value = default; 

到早期的 c# 代码?

【问题讨论】:

    标签: c#-3.0 c#-8.0


    【解决方案1】:

    表达式value is TimeSpan ts 检查value 的运行时类型,如果其类型为TimeSpan,则将该值复制到ts 变量中。装箱的值类型将作为复制的一部分被拆箱。

    请注意,System.TimeSpan,大概是您在这里处理的类型,是值类型,因此 as 运算符兼容,这是返回引用所必需的类型(以便在类型不正确时返回null)。

    因此,在您的示例中,您需要检查类型,然后明确取消对值的装箱,如下所示:

    ...
    else if (value is TimeSpan)
    {
        TimeSpan ts = (TimeSpan)value;
    
        parsedValue = ts.TotalDays.ToInvariantString();
        parsed = true;
        SetTimeSpanFormat(style);
    }
    ...
    

    第二个更简单,因为default 可以替换为default(T)。例如。 value = default(T);.

    【讨论】:

      【解决方案2】:

      C# 7:is 运算符模式或带模式的 Is-expression

      Reference

      if (value is TimeSpan ts)
      

      C# 3:is 和 as 运算符

      Reference 1, 2

      TimeSpan? ts = value as TimeSpan?;
      if (ts.HasValue) 
         ...
      

      if (value is TimeSpan) 
         TimeSpan ts = (TimeSpan)value;
      

      C# 7:默认文字

      Reference

      value = default;
      

      C# 3:默认操作符

      Reference

      value = default(T);
      

      【讨论】:

      • 上述as的使用不适用于值类型,TimeSpan是值类型。此外,如果您打算使用as,那么只需开始使用as,并将结果与​​null进行比较以进行类型检查会更有意义,例如MyReferenceType mrt = value as MyReferenceType; if (mrt != null) { ... }
      • @PeterDuniho 你说得对,我没有注意类型本身。我已经更新了我的帖子。
      • 好吧,除了现在你已经提议使用 TimeSpan? 这在 OP 的情况下是无用的,因为他们仍然需要转换为 TimeSpan 来访问结构的成员,或者他们将拥有改为使用ts.Value。正如我之前提到的,如果你要使用as 运算符,那么从is 开始是没有意义的;只需从as 开始,然后检查null 的结果。
      • @PeterDuniho 该替代方案也包含在帖子中。
      • 我描述的问题在我写评论的时候就已经存在了。看起来您利用编辑宽限期修改了帖子,而没有在修订中生成新的编辑记录。我仍然质疑使用TimeSpan? 的实用性,因为它除了增加开销和额外的代码行之外什么也没做。但至少现在您的帖子在技术上没有任何错误
      猜你喜欢
      • 1970-01-01
      • 2011-07-17
      • 1970-01-01
      • 2020-12-11
      • 2019-10-13
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      相关资源
      最近更新 更多