Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/replaysMike/AnyDiff
A CSharp (C#) diff library that allows you to diff two objects and get a list of the differences back.
https://github.com/replaysMike/AnyDiff
csharp csharp-code diff difference difference-between difference-generator differences-detected dotnet-core dotnet-standard
Last synced: 1 day ago
JSON representation
A CSharp (C#) diff library that allows you to diff two objects and get a list of the differences back.
- Host: GitHub
- URL: https://github.com/replaysMike/AnyDiff
- Owner: replaysMike
- License: other
- Created: 2018-11-16T05:36:27.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2024-06-18T01:21:03.000Z (5 months ago)
- Last Synced: 2024-10-30T08:16:47.459Z (15 days ago)
- Topics: csharp, csharp-code, diff, difference, difference-between, difference-generator, differences-detected, dotnet-core, dotnet-standard
- Language: C#
- Homepage:
- Size: 217 KB
- Stars: 161
- Watchers: 7
- Forks: 16
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AnyDiff
[![nuget](https://img.shields.io/nuget/v/AnyDiff.svg)](https://www.nuget.org/packages/AnyDiff/)
[![nuget](https://img.shields.io/nuget/dt/AnyDiff.svg)](https://www.nuget.org/packages/AnyDiff/)
[![Build status](https://ci.appveyor.com/api/projects/status/6vxd3cq83kuo4hg1?svg=true)](https://ci.appveyor.com/project/MichaelBrown/anydiff)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a79c138869504a359a064a98aa74908a)](https://www.codacy.com/app/replaysMike/AnyDiff?utm_source=github.com&utm_medium=referral&utm_content=replaysMike/AnyDiff&utm_campaign=Badge_Grade)
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/a79c138869504a359a064a98aa74908a)](https://www.codacy.com/app/replaysMike/AnyDiff?utm_source=github.com&utm_medium=referral&utm_content=replaysMike/AnyDiff&utm_campaign=Badge_Coverage)A CSharp (C#) diff library that allows you to diff two objects and get a list of the differences back.
## Description
AnyDiff works with complex objects of any type, and is great for performing changeset tracking, auditing, or anything else that might require comparing differences between complex objects. Great when combined with AnyClone, as it lets you take a snapshot of the current state of an object and then compare it in the future for changes to it.
It can even do this for objects that are of different types, though the results may vary depending on how different they are.
## Installation
Install AnyDiff from the Package Manager Console:
```powershell
PM> Install-Package AnyDiff
```## Usage
Comparing two objects with no differences:
```csharp
using AnyDiff;var object1 = new MyComplexObject(1, "A string");
var object2 = new MyComplexObject(1, "A string");
var diff = AnyDiff.Diff(object1, object2);
Assert.AreEqual(diff.Count, 0);
```Alternate extension syntax is also available (we will use this in further examples):
```csharp
using AnyDiff.Extensions;var object1 = new MyComplexObject(1, "A string");
var object2 = new MyComplexObject(1, "A string");
var diff = object1.Diff(object2);
Assert.AreEqual(diff.Count, 0);
```Comparing two objects with a single expected change:
```csharp
var object1 = new MyComplexObject(1, "A string");
var object2 = new MyComplexObject(1, "A different string");
var diff = object1.Diff(object2);
Assert.AreEqual(diff.Count, 1);
```Comparing objects using custom Type Converters for proper delta detection:
```csharp
public class MyComplexObject
{
public int Id { get; private set; }///
/// Convert a formatted string as a TimeSpan
///
[TypeConverter(typeof(TimeSpanConverter))]
public string StartTime { get; set; }public TypeConverterObject(int id, string startTime)
{
Id = id;
StartTime = startTime;
}
}var object1 = new MyComplexObject(1, "04:00:00");
var object2 = new MyComplexObject(1, "04:05:00");
var diff = object1.Diff(object2);
Assert.AreEqual(diff.Count, 1);
Assert.AreEqual(TimeSpan.FromMinutes(5), diff.First().Delta); // difference of 5 minutes
```### Ignoring Properties
Anydiff will ignore fields and properties decorated using attributes: `[IgnoreDataMember]`, `[NonSerialized]`, and `[JsonIgnore]`.
In addition, you can specify properties to ignore using expression syntax.
See [Ignoring Properties and Fields](https://github.com/replaysMike/AnyDiff/wiki/Ignoring-Properties-and-Fields) for more details.Ignoring by properties explicitly by passing a list of properties via expressions:
```csharp
var object1 = new MyComplexObject(1, "A string", true);
var object2 = new MyComplexObject(2, "A different string", true);
var diff = object1.Diff(object2, x => x.Id, x => x.Name);
Assert.AreEqual(diff.Count, 0);
```### Diff specified properties only
AnyDiff also supports processing of specific properties if you don't want to diff the entire object. This works using the same syntax as ignoring properties but passing a different ComparisonOptions. In the example below, only the properties `Id` and `Name` will be compared.
```csharp
var object1 = new MyComplexObject(1, "A string", true);
var object2 = new MyComplexObject(2, "A different string", true);
var diff = object1.Diff(object2, ComparisonOptions.All | ComparisonOptions.IncludeList, x => x.Id, x => x.Name);
Assert.AreEqual(diff.Count, 0);
```### Comparing Unordered lists
If you wish to perform a diff that ignores the ordering of data in a collection/list, you can specify that behavior with a ComparisonOptions `AllowCollectionsToBeOutOfOrder` flag as well as the `AllowEqualsOverride`, as seen below.
```csharp
var list1 = new List { 1, 2, 3 };
var list2 = new List { 1, 3, 2 };
var diff = list1.Diff(list2, ComparisonOptions.All | ComparisonOptions.AllowCollectionsToBeOutOfOrder | ComparisonOptions.AllowEqualsOverride);
Assert.AreEqual(diff.Count, 0);
```### Analyzing results
Viewing the results of a diff:
```csharp
var diff = object1.Diff(object2);foreach(var difference in diff)
{
Console.Write($"Index: {difference.ArrayIndex}"); // when array elements differ in value
Console.Write($"Delta: {difference.Delta}"); // when numbers, Dates, Timespans, strings differ in value
Console.Write($"Left: {difference.LeftValue}"); // the left value being compared
Console.Write($"Right: {difference.RightValue}"); // the right value being compared
Console.Write($"Property name: {difference.Property}"); // the name of the field/property
Console.Write($"Property type: {difference.PropertyType}"); // the type of the field/property
}```
### Scenarios supported
- [x] Circular references
- [x] Using TypeConverters to understand data types
- [x] Deltas on strings, DateTimes, TimeSpans, numeric types
- [x] Comparing arrays, collections, custom collections, dictionaries, hashtables
- [x] Comparing collections with different ordering
- [x] Complex objects, deep type inspection
- [x] Entity Framework objects
- [x] IEquatable support### Using with other libraries
Comparing the difference between the same object at different states, using [AnyClone](https://github.com/replaysMike/AnyClone)
```csharp
using AnyDiff.Extensions;
using AnyClone;var object1 = new MyComplexObject(1, "A string");
var object1Snapshot = object1.Clone();var diff = object1.Diff(object1Snapshot);
Assert.AreEqual(diff.Count, 0);// change something anywhere in the object tree
object1.Name = "A different string";diff = object1.Diff(object1Snapshot);
Assert.AreEqual(diff.Count, 1);
```