https://github.com/ufcpp/noncopyableanalyzer
An analyzer for Non-Copyable structs.
https://github.com/ufcpp/noncopyableanalyzer
Last synced: 6 months ago
JSON representation
An analyzer for Non-Copyable structs.
- Host: GitHub
- URL: https://github.com/ufcpp/noncopyableanalyzer
- Owner: ufcpp
- License: mit
- Created: 2017-12-12T05:54:51.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2022-06-23T01:46:36.000Z (over 3 years ago)
- Last Synced: 2024-12-04T17:17:04.543Z (about 1 year ago)
- Language: C#
- Homepage:
- Size: 143 KB
- Stars: 31
- Watchers: 6
- Forks: 4
- Open Issues: 7
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# NonCopyableAnalyzer
Some kind of structs should not be copied (especially mutable structs).
This package contains an analyzer for such a struct.
NuGet: [https://www.nuget.org/packages/NonCopyableAnalyzer/](https://www.nuget.org/packages/NonCopyableAnalyzer/)
## Example
A typical example of a non-copyable struct is [`ResizableArray`](https://github.com/dotnet/corefxlab/blob/master/src/System.Collections.Sequences/System/Collections/Sequences/ResizableArray.cs).
So I'll use it for explanation. Let's copy it from [corefxlab](https://github.com/dotnet/corefxlab/blob/master/src/System.Collections.Sequences/System/Collections/Sequences/ResizableArray.cs) and add an attribute named `NonCopyable`.
```cs
namespace System.Collections.Sequences
{
// copy from corefxlab
// a List like type designed to be embeded in other types
// this kind of type should not be copied
[NonCopyable]
public struct ResizableArray
{
...
}
```
The analyzer checks the attribute only by name - any namespace, both internal and public are OK.
```cs
using System;
[AttributeUsage(AttributeTargets.Struct)]
internal class NonCopyableAttribute : Attribute { }
```
Now, the analyzer reports misuse of the non-copyable struct.
### Misuse 1: pass by value
```cs
using System.Collections.Sequences;
class Program
{
static void Main()
{
var a = new ResizableArray();
// do not pass a non-copyable by value
AddUtf16(a, "abcd");
}
static void AddUtf16(ResizableArray a, string s)
{
foreach (var c in s)
{
a.Add((short)c);
}
}
}
```

### Misuse 2: read-only
```cs
using System.Collections.Sequences;
class Program
{
static void Main()
{
var a = new ResizableArray();
AddUtf16(a, "abcd");
}
static void AddUtf16(in ResizableArray a, string s)
{
foreach (var c in s)
{
// do not invoke methods/properties with ref readonly
a.Add((short)c);
}
}
}
```

### How to fix
In this case, you should use `ref` parameter.
```cs
using System.Collections.Sequences;
class Program
{
static void Main()
{
var a = new ResizableArray();
AddUtf16(ref a, "abcd");
}
static void AddUtf16(ref ResizableArray a, string s)
{
foreach (var c in s)
{
a.Add((short)c);
}
}
}
```