【问题标题】:Generic as null in int,decimal,Datetime types在 int、decimal、Datetime 类型中泛型为 null
【发布时间】:2020-12-05 00:15:04
【问题描述】:

我有这个方法:

  public static DiffModule<T> AddValue<T>(T Source, T Destination)
    {
        DiffModule<T> module = new DiffModule<T>();
        module.Source = Source;
        module.Desctination = Destination;

        var type = typeof(T);
       
        
            //Check nullable
            if(Source==null && Destination == null)
            {
                module.Result = CompareResult.Equal;
                return module;
            }
            if (Source == null)
            {
                module.Result = CompareResult.NotExistInSource;
                return module;
            }
            if (Destination == null)
            {
                module.Result = CompareResult.NotExistInDestination;
                return module;
            }
       

        
        module.Result = (EqualityComparer<T>.Default.Equals(Source, Destination)) ? CompareResult.Equal : CompareResult.NotEqual;

        return module;
    }

public enum CompareResult
{
    Undefined,
    Equal,
    NotEqual,
    NotExistInSource,
    NotExistInDestination
}

如果我愿意

 var m1 = DiffModule<string>("Hi there",null);

这将返回 NotExistInDestination 枚举结果,但如果我愿意尝试

 var m2 = DiffModule<int>(2,null) <-- that of course is an error

如何“使” int、double、decimal、datetime 类型作为可空传递给 AddValue 方法? 请考虑数据可以从固定值类型的 VO 传递

例如:public DateTime EndDate {get; set;} 不能是 public DateTime? {get;set;}

【问题讨论】:

  • 虽然我不确定我是否完全理解了这个问题...AddValue&lt;int?&gt;(2, null);AddValue(2, (int?)null); ?
  • 试过 DiffModule.AddValue(4, null) null throw error can't convert to double - 也试过 (double?)null - 没用
  • 作为问题的切线解决方案,您可以将泛型参数设为可空 (example fiddle),前提是您知道该类型不可为空。
  • 您的代码中的部分问题是您的相等比较逻辑存在于包含存储的通用值的类的外部(即DiffModule&lt;T&gt;)。如果此逻辑封装在 DiffModule&lt;T&gt; 中,您将能够考虑所有可为空与不可为空的情况,同时还为外部消费者提供可重用的接口。
  • "那当然是一个错误" 你从来没有展示过DiffModule&lt;&gt; 的类定义,也没有你得到的实际错误,所以无法判断。我们可以猜测你的构造函数定义可能是什么,但最好是查看实际代码而不是猜测它可能是什么。

标签: c#


【解决方案1】:

问题是值类型不能是null,故事结束。当您向单个泛型参数提供 null值类型 时,编译器(通过 静态分析)会正确地通知您有问题。

无法从 转换为

因为,它不可转换!所以没有隐式转换……

您也无法添加 约束 或修改签名以推断 可为空(在这种情况下)或 anti-lift(只是编造的)一个值类型和引用类型..

你所能做的就是显式地通过类型参数告诉编译器你想要什么,或者将null转换成它的nullable对应物:

AddValue<int?>(2, null); 

// or

AddValue(2, (int?)null);

【讨论】:

  • 试过这个 - 有编译器错误 - T - 当它是类的属性时不能为空
  • @Izikon 为我工作dotnetfiddle.net/MruvKQ
  • 有效!。问题出在属性上-我需要绕过它...
【解决方案2】:

在C#中一般的T不能为空,你应该使用"T?" 问号表示一个可以为空的值当然可以为空结束你可以对这个值进行null检查。 同样基本上在 C# 原始类型中不能为空,但从 C# 2 开始,可以使用问号表示法,如 int?布尔?浮动?

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多