How to get an error shown when using non strings a

2019-07-16 14:22发布

The suggested duplicate is indeed a similar question. However, the answer there covers only one option - disabling the ToString() itself. There are other possible solutions such as having Visual Studio warn me about it, or have the ToString() not be called (read the answer there carefully, he assumes it is called, and just explains that there is no way of "removing" ToString().), or use a lower version of C# (did it always work this way?), etc...

When I have a non string somewhere where a string is expected by the code I don't want it automatically converted to string. I want an error. For example:

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

And Data is a byte[] I DON'T want to get:

System.Byte[]

I want to get an error so I know I need to fix it. (There's a reason for strong typing.)

So, is there a way to get Visual-Studio/C#/.Net to show me an error/throw-an-Exception when using non strings as strings?

3条回答
我欲成王,谁敢阻挡
2楼-- · 2019-07-16 14:58

Rosyln analyzers can be installed in your project using Nuget in Visual Studio 2017.

In particular there is a Rosyln analyzer that checks for implicit and explicit calls to ToString() if ToString() is not overridden in the class. https://www.nuget.org/packages/ToStringWithoutOverrideAnalyzer/

Installed analyzers can be found under references

enter image description here

By default this analyzer will produce warnings as shown by the triangle with !, but right clicking on the rules you can elevate any rule to be an error, or reduce it to informational.

Potential gotcha

Console.Write and Console.WriteLine have several overloads including Console.Write(object value), so if you are printing some object that hasn't overridden ToString() like Console.Write(myCustomObject) the analyzer will not catch this because there is no implicit conversion being made (at least in the code that you have written)

查看更多
Ridiculous、
3楼-- · 2019-07-16 15:01

When you have a string type and use the + operator then it will call the virtual ToString() method for any type that isn't a string automatically.

You can't avoid this by just adding types to produce a string (at least not in a simple or practical manner).

You can do something else instead; such as

return (Data is string value) 
       ? value + Environment.NewLine
       : throw new Exception("Not a string"); //or return whatever else you want here.

If you want to make sure Data is always a string without testing then I would pass it to the method as a parameter.

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

And the obvious case; if you want Data to be a field and always a string is to declare Data as a string to start with.

Edit:

As stated in comments above; I now understand that you want to basically flag any use of virtual ToString() calls to prevent operations like this from happening. A comment was given to update the Roslyn Analyzer and a link to where that's already been done before. I'm not posting those comments here to steal the answer but I do agree that, that may be the best solution for what you want. Another option would be to use reflection but that wouldn't work until runtime.

查看更多
老娘就宠你
4楼-- · 2019-07-16 15:11

You can explicitly try cast Data and VS will complain if its not a string

public string Stringify()
{
    return (string)Data + Environment.NewLine;
}
查看更多
登录 后发表回答