C# 当使用非字符串作为字符串(而不是自动使用ToString)时,如何显示错误?

C# 当使用非字符串作为字符串(而不是自动使用ToString)时,如何显示错误?,c#,.net,visual-studio,C#,.net,Visual Studio,建议的副本确实是一个类似的问题。但是,答案只包括一个选项——禁用ToString()本身。还有其他可能的解决方案,比如让Visual Studio警告我,或者不调用ToString()(仔细阅读答案,他假设它被调用了,只是解释说没有办法“删除”ToString()),或者使用较低版本的C#(它总是这样工作吗?),等等 当我有一个非字符串的地方,代码期望有一个字符串,我不希望它自动转换成字符串。我想要一个错误。例如: public string Stringify() { return D

建议的副本确实是一个类似的问题。但是,答案只包括一个选项——禁用ToString()本身。还有其他可能的解决方案,比如让Visual Studio警告我,或者不调用ToString()(仔细阅读答案,他假设它被调用了,只是解释说没有办法“删除”ToString()),或者使用较低版本的C#(它总是这样工作吗?),等等

当我有一个非字符串的地方,代码期望有一个字符串,我不希望它自动转换成字符串。我想要一个错误。例如:

public string Stringify()
{
    return Data + Environment.NewLine;
}
数据
是一个
字节[]
我不想得到:

系统字节[]

我想得到一个错误,所以我知道我需要修复它。(强输入是有原因的。)


那么,有没有办法让Visual Studio/C#/.Net在使用非字符串作为字符串时显示错误/引发异常?

您可以显式地尝试强制转换数据,如果不是字符串,VS会抱怨

public string Stringify()
{
    return (string)Data + Environment.NewLine;
}

当您有一个
字符串
类型并使用
+
操作符
时,它将自动为任何非
字符串的类型调用
虚拟ToString()
方法

您不能通过添加类型来生成
字符串来避免这种情况(至少不能以简单或实用的方式)

你可以做些别的事情;比如

return (Data is string value) 
       ? value + Environment.NewLine
       : throw new Exception("Not a string"); //or return whatever else you want here.
如果您想确保
数据
始终是
字符串
,而不进行测试,那么我会将其作为参数传递给方法

public string Stringify(string data)
{
    return data + Environment.NewLine;
}
以及显而易见的情况;如果希望
数据
成为一个字段,并且始终是
字符串
,则首先将
数据
声明为
字符串

编辑:


如上述评论所述;我现在了解到,您基本上希望标记任何使用
virtual-ToString()
调用的情况,以防止此类操作发生。给出了更新Roslyn分析仪的注释,并链接到之前已经完成的地方。我不是在这里发表这些评论来窃取答案,但我同意,这可能是你想要的最好的解决方案。另一种选择是使用反射,但这在运行时才起作用。

可以使用Visual Studio 2017中的Nuget在项目中安装Rosyln分析器

特别是,如果类中未重写
ToString()
,则Rosyln分析器会检查对
ToString()的隐式和显式调用

已安装的分析仪可在参考中找到

默认情况下,此分析器将产生警告,如带
的三角形所示,但右键单击规则可以将任何规则提升为错误,或将其降低为信息性规则

潜在的陷阱
Console.Write
Console.WriteLine
有几个重载,包括
Console.Write(object value)
,因此如果您打印的对象没有覆盖
ToString()
Console.Write(myCustomObject)
分析器不会捕捉到这一点,因为没有进行隐式转换(至少在您编写的代码中是这样)

如果我注意到它不是字符串,我会已经修复它。如果你建议我在任何地方都要习惯这样做,那确实会有帮助,但这太麻烦了。你可以随时编写自己的Roslyn分析器并检测对非字符串对象的隐式
.ToString()
调用。可能不是简单的解决方案,我想…@Thowk谢谢!虽然我同意这不是一个简单的解决方案,但这是我问题的第一个真正答案。请随意将其作为答案发布。绝对值得投一票。@ispiro你能更新一下这个问题吗?您正在抱怨强类型,但您允许
数据
为任何类型。如果
数据
被声明为
字符串
,则它将始终是
字符串
,并且当您滥用它时,编译器将发出抱怨。已经有一个rosyln分析器,当隐式地在没有重写Microsoft在此编写的ToString的对象上使用ToString时,它会生成警告。我没有使用Rosyln分析仪的经验,所以其他人可以将此转化为完整的答案。(不是投票人)请看我对另一个答案的评论。@ispiro Ok,也许我误解了这个问题。你到底希望发生什么?我希望这样做,以防我编写了有问题的代码(因为我忘了将
数据
转换为十六进制或其他形式),以获得某种通知,这样我就知道我需要修复它。就像我在C#中其他地方使用错误的类型一样。然后我建议始终将
数据
作为
字符串
参数传递给该方法。