ThinkMeta.CodeAnalysis.CSharp
1.0.14
See the version list below for details.
dotnet add package ThinkMeta.CodeAnalysis.CSharp --version 1.0.14
NuGet\Install-Package ThinkMeta.CodeAnalysis.CSharp -Version 1.0.14
<PackageReference Include="ThinkMeta.CodeAnalysis.CSharp" Version="1.0.14" />
<PackageVersion Include="ThinkMeta.CodeAnalysis.CSharp" Version="1.0.14" />
<PackageReference Include="ThinkMeta.CodeAnalysis.CSharp" />
paket add ThinkMeta.CodeAnalysis.CSharp --version 1.0.14
#r "nuget: ThinkMeta.CodeAnalysis.CSharp, 1.0.14"
#:package ThinkMeta.CodeAnalysis.CSharp@1.0.14
#addin nuget:?package=ThinkMeta.CodeAnalysis.CSharp&version=1.0.14
#tool nuget:?package=ThinkMeta.CodeAnalysis.CSharp&version=1.0.14
ThinkMeta.CodeAnalysis
Static code analyzer for C#
ThinkMeta.CodeAnalysis.CSharp<br>
Overview
ThinkMeta.CodeAnalysis is a static code analyzer for C# projects, built on Roslyn. It helps developers identify code issues, enforce coding standards, and improve code quality automatically.
Features
- Detects common code issues and anti-patterns
- Supports custom analyzers and code fixes
- Integrates with .NET build and IDE tooling
- Targets .NET Standard 2.0 for broad compatibility
Diagnostics
TM0001: Use pattern matching for null checks
Description:
Warns when using == null or != null for null checks.
Reason:
Pattern matching (is null, is not null) is preferred for clarity and future-proofing code.
How to fix:
Replace == null with is null, and != null with is not null.
Exceptions:
Null checks using == null or != null inside expression trees (e.g., lambdas assigned to Expression<Func<...>>) are not reported by this diagnostic, as pattern matching is not supported in expression trees.
Examples:
// Standard null check
if (obj == null) { }
// =>
if (obj is null) { }
// Query syntax
var q = from o in arr where o == null select o;
// =>
var q = from o in arr where o is null select o;
// Razor-generated (in .g.cs from .razor)
@if (Model == null) { <text>Empty</text> }
// =>
@if (Model is null) { <text>Empty</text> }
// No warning in expression trees
Expression<Func<object, bool>> expr = o => o == null; // No diagnostic
TM0002: Clone method is missing a property assignment
Description:
Warns when a Clone() method (returning the containing type or object) does not assign all settable, non-excluded properties.
Reason:
Forgetting to assign a property in a Clone() method leads to silent data loss that is hard to detect at runtime.
How to fix:
The accompanying code fix adds all missing property assignments in a single edit, for both object-initializer and statement-based clone patterns.
Exclusions:
Properties are skipped when they have no setter, are private, or when the method uses MemberwiseClone(). Use [CloneIgnore] to explicitly exclude properties by name (see below).
Examples:
// Missing property — TM0002 fires on "Clone"
class C
{
public int X { get; set; }
public int Y { get; set; }
public C Clone() => new C { X = this.X }; // TM0002: does not assign: 'Y'
}
// After applying the code fix:
public C Clone() => new C { X = this.X, Y = this.Y };
TM0003: Clone method performs a shallow copy of a reference-type property
Description:
Warns when a Clone() method copies a reference-type property directly from this, producing a shallow copy.
Reason:
Shallow copying a reference type shares the same object between the original and the clone, which can lead to unintended mutations.
How to fix:
Replace this.Prop with a proper deep copy (e.g., this.Prop.Clone(), new T(this.Prop), etc.).
Exceptions:
string is exempt because it is immutable. Private properties and properties excluded via [CloneIgnore] are also skipped.
Examples:
class Inner { }
class C
{
public Inner Item { get; set; }
// TM0003 fires on "this.Item" — shallow copy of reference type
public C Clone() => new C { Item = this.Item };
}
CloneIgnoreAttribute
Use [CloneIgnore("PropName")] to suppress TM0002/TM0003 for specific properties. The attribute is shipped as a content file and compiled into the consuming project automatically.
Method level — exclude a property for one Clone method:
[CloneIgnore(nameof(Computed))]
public MyClass Clone() => new MyClass { Id = this.Id }; // 'Computed' is not reported
Assembly level — exclude a property across all Clone methods in the assembly (e.g. in AssemblyInfo.cs):
[assembly: ThinkMeta.CodeAnalysis.Annotations.CloneIgnore("AdditionalProperties")]
Multiple properties and multiple attributes are supported:
[assembly: ThinkMeta.CodeAnalysis.Annotations.CloneIgnore("AdditionalProperties", "Computed")]
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.16 | 101 | 5/18/2026 |
| 1.0.15 | 92 | 5/17/2026 |
| 1.0.14 | 91 | 5/17/2026 |
| 1.0.13 | 107 | 5/10/2026 |
| 1.0.12 | 103 | 5/10/2026 |
| 1.0.11 | 128 | 1/3/2026 |
| 1.0.10 | 121 | 1/3/2026 |
| 1.0.9 | 115 | 1/2/2026 |
| 1.0.8 | 117 | 1/2/2026 |
| 1.0.7 | 111 | 1/2/2026 |
| 1.0.6 | 122 | 1/2/2026 |
| 1.0.5 | 190 | 12/14/2025 |
| 1.0.4 | 435 | 11/20/2025 |
| 1.0.3 | 423 | 11/20/2025 |
| 1.0.2 | 424 | 11/20/2025 |
| 1.0.1 | 409 | 11/20/2025 |
| 1.0.0 | 427 | 11/20/2025 |
CloneIgnoreAttribute is now shipped as a compiled assembly (ThinkMeta.CodeAnalysis.Annotations.dll) under the ThinkMeta.CodeAnalysis.Annotations namespace, replacing the previous source content file.