【问题标题】:Construct c# code with different output, only difference should be Nullable<int> vs. int?构造具有不同输出的 c# 代码,唯一的区别应该是 Nullable<int> 与 int?
【发布时间】:2014-08-27 10:28:57
【问题描述】:

正如我一样,recently found out int?Nullable&lt;int&gt; 并不总是可以互换的。 (当然,对于具有 Nullable 对应项的所有类型都是如此,而不仅仅是 int。)

我想知道的是:有没有一种方法可以构建有效的 C# 代码,您可以在其中将 int? 替换为 Nullable&lt;int&gt;一些 出现,所以不是全部,但不一定只有一个)并获得仍然有效的 C# 代码,但含义不同?

我不把int?Nullable&lt;int&gt; 是字符串文字的一部分的例子算作解决方案,所以这个微不足道的情况不是我要找的:

if ("int?".Contains("int?"))
    Console.WriteLine("true");
else
    Console.WriteLine("false");
// prints "true"

if ("int?".Contains("Nullable<int>"))
    Console.WriteLine("true");
else
    Console.WriteLine("false");
// prints "false"

这里还有一个更复杂的版本,它仍然使用字符串,但向您展示了编写代码很可能只有这种差异导致不同的含义(不幸的是只有一个版本是有效的 C#):

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerResults results = codeProvider.CompileAssemblyFromSource(new CompilerParameters(), "using System; class Foo { static void Main() { int a=1; var test = a is Nullable<byte> & true; } }");
Console.WriteLine(results.Errors.Count > 0 ? "false" : "true");
// prints "true"

CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
CompilerResults results = codeProvider.CompileAssemblyFromSource(new CompilerParameters(), "using System; class Foo { static void Main() { int a=1; var test = a is byte? & true; } }");
Console.WriteLine(results.Errors.Count > 0 ? "false" : "true");
// prints "false"

(关于为什么一个编译而另一个不编译,我建议你查看这个questionanswer。)

所以我的问题是你能构造这样的代码吗?如果没有,那为什么不呢?

【问题讨论】:

  • 你检查过Nullable&lt;byte&gt;情况下的编译错误吗?
  • 我不同意这个前提;它们总是可以互换的,但确保结果是有效的 C# 是你的工作;括号应该是你的解决方法......在这两种情况下添加括号可以避免问题(var test = (a is int?) &amp; b;var test2 = (a is Nullable&lt;int&gt;) &amp; b;
  • @YoryeNathan 你是什么意思?在这种情况下,第二个示例应该编译得很好。错误来自字节?,并且该错误在linked answer中进行了解释,它与“?”有关token 被识别为三元运算符而不是类型修饰符。这是这个问题背后的主要思想。使用此信息可能会创建这样的代码...
  • 相关,关于在三元运算符中使用?的问题:stackoverflow.com/questions/24305290/…
  • @MarcGravell 是的,永远不应该编写这样的代码,但我并不是要避免这个问题,而是要滥用它。 :) 你知道,玩得开心。

标签: c# nullable


【解决方案1】:

好吧,一个简单的例子就是声明一个名为Nullable&lt;T&gt;的本地类型; int 将始终解析为 global::System.Int32T? 上的 ? 后缀将始终解析为 global::System.Nullable&lt;T&gt;,但手动编写的 Nullable&lt;T&gt; 将使用常规规则解析 - 这意味着它可能不是你的那个预期:

static void Main()
{
    string s = (new Nullable<int>(123)).GetType().Assembly.FullName;
    string t = (new int?(123)).GetType().Assembly.FullName;
}
struct Nullable<T> {public Nullable(T value){} }

【讨论】:

  • 聪明。不完全是我的预期:)
猜你喜欢
  • 1970-01-01
  • 2014-09-30
  • 2020-01-05
  • 2020-09-03
  • 2022-07-06
  • 2019-06-13
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
相关资源
最近更新 更多