dustincampbell / csharpessentials Goto Github PK
View Code? Open in Web Editor NEWC# Essentials is a collection of Roslyn diagnostic analyzers, code fixes and refactorings that make it easy to work with C# 6 language features.
License: Other
C# Essentials is a collection of Roslyn diagnostic analyzers, code fixes and refactorings that make it easy to work with C# 6 language features.
License: Other
class C {
int Property {
[A] get { return 42; }
}
}
class C
{
public C()
{
Instance = this;
}
public static C Instance { get; private set; }
}
The diagnostics should ignore any code in classes/methods decorated with System.CodeDom.Compiler.GeneratedCodeAttribute.
The following two tests demonstrate this issue. I had a look through the code to see if I can fix it, found the Extensions.IsGeneratedcode method, but got stuck past that as I'm not sure how to determine if the node being analysed is in the context of a GeneratedCode attribute.
[Test]
public void VerifyNotAvailableInClassWithGeneratedCodeAttribute()
{
const string code = @"
using System;
[System.CodeDom.Compiler.GeneratedCode()]
class C
{
void M(int x)
{
throw new ArgumentNullException(""x"");
}
}";
NoDiagnostic(code, DiagnosticIds.UseNameOf);
}
[Test]
public void VerifyNotAvailableInMethodWithGeneratedCodeAttribute()
{
const string code = @"
using System;
class C
{
[System.CodeDom.Compiler.GeneratedCode()]
void M(int x)
{
throw new ArgumentNullException(""x"");
}
}";
NoDiagnostic(code, DiagnosticIds.UseNameOf);
}
First, thanks for the great analyzers! I'm really enjoying them. However, I discovered today that CSE0003 (Consider using an expression-bodied member) loses comments from a member body when it converts it to an expression. For example, given this method:
protected virtual bool ReadOptions(string changedOptionId)
{
// If we're passed a specific option ID, then return false because we can't read it here to tell if it changed.
// If we're passed null or empty, then return true as if something changed.
return string.IsNullOrEmpty(changedOptionId);
}
CSE0003 turned that into:
protected virtual bool ReadOptions(string changedOptionId) => string.IsNullOrEmpty(changedOptionId);
But I expected something like the following where the comments are preserved:
// If we're passed a specific option ID, then return false because we can't read it here to tell if it changed.
// If we're passed null or empty, then return true as if something changed.
protected virtual bool ReadOptions(string changedOptionId) => string.IsNullOrEmpty(changedOptionId);
I suppose it gets tricky if XML doc comments are also used, so maybe the member body comments should go before or after the arrow operator. Or maybe CSE0003 shouldn't recommend a change if the member body contains comments. I'm not sure what would be best, but since this fix can be applied globally to a solution, it would be nice if it didn't lose data in these situations.
Thanks!
I've got an ASP.NET Core project with some .cshtml files. CSE0002 is raised on the .cshtml file even though there is no code in the .cshtml file.
Consider the following code.
Preconditions.GreaterThanOrEqual(maxCount, "maxCount", minCount, "minCount");
C# Essentials will only detect "maxCount" but not "minCount" as a candidate to replace with nameof operator.
Also, I absolutely love this extension. It's made updating my codebase so easy!
This is an enhancement request.
It would be great to be able to very quickly being able to toggle (meaning adding or removing) the $ (dollar) in front of the string where the caret is.
Since C# 6.0 is out there, I rarely use string.Format
, but almost always $"..."
instead.
I often find myself start writing a regular string "..."
and then in the middle of my typing, I figure out I need to put a variable, so I start to add an open brace, then my variable, and then I figure out that I forgot the $
symbol in the first place.
So I have to navigate back to the beginning of the string, sometimes by pressing Home
key then Ctrl + Right Arrow
key several times, or just Ctrl + Left Arrow
several times, or with the mouse.
No need to say that all of those ways to do it are quite slow, and somehow frustrating, since it happens quite often.
Having a shortcut, such as Ctrl + Alt + D
(for Dollar), Ctrl + Alt + F
(for Format), or even simpler Ctrl + 4
(because 4 maps to the dollar symbol on US keyboard) that, when the caret is in the middle of a string, appends the $
symbol in front of the string if there is not, and remove it if there is.
I guess a Quick Action could make it, however it may not be as fast to do so, for example if other extensions add more Quick Actions in the same context, it might still require several key presses to get the job done.
Do you have any plan to support Visual Studio 2017/VSIX v3?
Some functionality in this analyzer was integrated into VS 2017, but some was not, e.g. CSE0003: "Consider using an expression-bodied member". I would like to use them in VS 2017.
Hi,
It would be great.
Thanks.
As mentioned on Visual Studio Gallery datamembers properties cannot be turned into getter-only as this breaks deserialization.
I encountered the issue while using protobuf-net
and its [ProtoContract]
attribute.
It doesn't appear to recognise String.Format as a refactoring in this case
I'm not sure if this is a bad design paradigm but I use it all the time. Consider the following code.
public class DailySchedule
{
private int _recursEveryNumberOfDays;
public int RecursEveryNumberOfDays
{
get
{
return _recursEveryNumberOfDays;
}
set
{
Preconditions.GreaterThanOrEqual(value, "RecursEveryNumberOfDays", 1);
_recursEveryNumberOfDays = value;
}
}
public DailySchedule(int recursEveryNumberOfDays = 1)
{
RecursEveryNumberOfDays = recursEveryNumberOfDays;
}
}
C# Essentials will not detect "RecursEveryNumberOfDays" as a candidate for a nameof replacement.
Also consider the following in a web situation.
public static string UserID
{
get
{
return (string)Session["UserID"];
}
set
{
Session["UserID"] = value;
}
}
It would be great if a warning could be raised when a switch (myEnum)
is missing a value case.
... so that your code can be consumed by non VS users :)
I've been using C# Essentials since 2015. Since it has no official NuGet package, I've been reluctantly checking the DLL into source control to ensure it's available in every developer's environment. Recently, I got tired of doing that and decided to see what it would take to replace C# Essentials. In the Q&A section on C# Essentials - Visual Studio Marketplace, @DustinCampbell said on Nov 21, 2017:
There's not a need to support this extension for VS 2017 because most of its features are already included in VS itself. With the latest updates to VS 2017, you'll find that there are several code fixes and refactorings for transitioning your code to C# 7.
In Visual Studio 2022 and .NET 8, I found four of the five C# Essentials features built-in:
So, the only thing missing was UseGetterOnlyAutoProperty (CSE0002). I reimplemented it in my Menees.Analyzers library in release 3.1.0. I had to rewrite it to be compliant with modern Roslyn coding practices (e.g., to avoid GetSemanticModel per rule RS1030). I took the opportunity to make it ignore properties with attributes since they're typically used with reflection and/or serialization. I also updated it to handle some new C# syntax, e.g., null-coalescing assignment, local functions, and record types. And I made the code fixer handle some whitespace formatting cases better.
I hope this helps folks looking for equivalent functionality.
The error pane shows the warning:
Warning AD1002 Unable to load Analyzer assembly C:\APPDATA\LOCAL\MICROSOFT\VISUALSTUDIO\14.0\EXTENSIONS\5FFBEBER.SPV\CSharpEssentials.dll: Could not load file or assembly 'CSharpEssentials, Version=1.0.5725.26970, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I have verified that the file is there, and even built the code using the RC. Not sure what would make this not work anymore, but it makes me very sad!
In the following code the CSE0003 warning is raised, implying it should be an expression bodied member when it cannot be because it isn't a single line. Worse is the suggested fix removes code.
private static string DeviceID()
{
#if WINDOWS_PHONE_APP
var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
var hardwareId = token.Id;
var dataReader = DataReader.FromBuffer(hardwareId);
byte[] bytes = new byte[hardwareId.Length];
dataReader.ReadBytes(bytes);
return BitConverter.ToString(bytes);
#endif
#if WINDOWS_UWP
return " arrgggh Windows 10";
#endif
}
I have a relatively old and relatively large codebase. I have disabled the CSE0003 warning because of the large amount of occurrences, but I change them manually whenever I edit the vicinity of the code. It would be very handy if the Ctrl+.
action item did not disappear when the warning is supressed.
The documentation did not hint that I could use a Ruleset file to lower the warning level into hidden. This prevents the display of warnings while keeping the codefix actions.
I tried this idea after reading the SonarLint FAQ, which pointed me to the ruleset file. I think a similar section should be added to the readme.
expressions like the following are not converted properly -
string.format("{0}", ((i > 0) ? "A" : "B"))
Just wanted to capture the suggestion made by @fsateler in issue #19 to allow users to annotate their own methods with a custom attribute which would allow the Convert to String Interpolation refactoring to run on them:
[FormatStringConsumer(FormatStringParameterNumber = 2)]
void WriteToDevice(Device d, string format, params object[] arguments) { ... }
Sorry, wrong project.
"Consider using a getter-only auto property" fix is incorrectly reported if static property is set from class constructor (not from static constructor).
public class MyClass
{
public static bool StaticProperty { get; private set; } //<- "Consider using a getter-only auto property" is reported here.
public MyClass()
{
StaticProperty = true;
}
}
In fact I get this in all cshtml files.
Currently, this diagnostic analyzer is incorrectly reported for any auto property with a "private set".
Consider the following:
class C
{
int P { get { return 42; } }
}
Results in:
class C
{
int P => 42; }
Found in the ASP.NET MVC codebase.
It'd be great to be able to apply the "Convert to String Interpolation" to .NET APIs other than just String.Format(). For example:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.