懒得勤快 1 mês atrás
pai
commit
0e130f9a2f

+ 1 - 1
Directory.Build.props

@@ -1,6 +1,6 @@
 <Project>
  <PropertyGroup>
-   <Version>2025.5</Version>
+   <Version>2025.5.1</Version>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
 </Project>

+ 2 - 2
Masuit.Tools.Abstractions/DateTimeExt/DateTimeHelper.cs

@@ -537,12 +537,12 @@ namespace Masuit.Tools.DateTimeExt
         /// <summary>
         /// 起始时间
         /// </summary>
-        public DateTime Start { get; set; }
+        public DateTime? Start { get; set; }
 
         /// <summary>
         /// 终止时间
         /// </summary>
-        public DateTime End { get; set; }
+        public DateTime? End { get; set; }
     }
 
     /// <summary>

+ 10 - 10
Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj

@@ -51,9 +51,9 @@
         <PackageReference Include="AngleSharp.Css" Version="1.0.0-beta.151" />
         <PackageReference Include="DnsClient" Version="1.8.0" />
         <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
-        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.8" />
-        <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
-        <PackageReference Include="System.Management" Version="9.0.8" />
+        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.9" />
+        <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
+        <PackageReference Include="System.Management" Version="9.0.9" />
         <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
         <PackageReference Include="SharpCompress" Version="0.40.0" />
     </ItemGroup>
@@ -64,7 +64,7 @@
         <PackageReference Include="System.Memory" Version="4.6.3" />
         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="[1.0.0]" />
         <PackageReference Include="SixLabors.ImageSharp" Version="[2.1.11]" />
-        <PackageReference Include="System.Collections.Immutable" Version="9.0.8" />
+        <PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
         <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="[7.0.0]" />
     </ItemGroup>
@@ -75,7 +75,7 @@
         <PackageReference Include="System.Memory" Version="4.6.3" />
         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="[1.0.0]" />
         <PackageReference Include="SixLabors.ImageSharp" Version="[2.1.11]" />
-        <PackageReference Include="System.Collections.Immutable" Version="9.0.8" />
+        <PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
         <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="[7.0.0]" />
     </ItemGroup>
@@ -83,23 +83,23 @@
     <ItemGroup Condition=" '$(TargetFramework)' == 'net6'">
         <PackageReference Include="Castle.Core" Version="5.1.1" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="[7.0.0]" />
-        <PackageReference Include="System.Collections.Immutable" Version="9.0.8" />
+        <PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
         <PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
     </ItemGroup>
 
     <ItemGroup Condition=" '$(TargetFramework)' == 'net8'">
         <PackageReference Include="Castle.Core" Version="5.2.1" />
-        <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.8" />
-        <PackageReference Include="System.Collections.Immutable" Version="9.0.8" />
+        <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.9" />
+        <PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
         <PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
     </ItemGroup>
 
     <ItemGroup Condition=" '$(TargetFramework)' == 'net9'">
         <PackageReference Include="Castle.Core" Version="5.2.1" />
-        <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.8" />
-        <PackageReference Include="System.Collections.Immutable" Version="9.0.8" />
+        <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.9" />
+        <PackageReference Include="System.Collections.Immutable" Version="9.0.9" />
         <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
         <PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
     </ItemGroup>

+ 2 - 1
Masuit.Tools.Abstractions/Media/ImageBorderRemover.cs

@@ -68,7 +68,8 @@ public class ImageBorderRemover
         byte toleranceValue = (byte)(tolerance * 2.55);
 
         // 使用多层边框检测算法
-        var (top, bottom, left, right, layers, colors) = FindContentBordersWithLayers(image, toleranceValue, maxLayers, useDownscaling, downscaleFactor);
+        using var clone = image.Clone(c => c.Grayscale());
+        var (top, bottom, left, right, layers, colors) = FindContentBordersWithLayers(clone, toleranceValue, maxLayers, useDownscaling, downscaleFactor);
 
         // 设置内容边界
         result.ContentTop = top;

+ 27 - 24
Masuit.Tools.Abstractions/Models/DateTimeRange.cs

@@ -1,6 +1,7 @@
-using Masuit.Tools.DateTimeExt;
-using System;
+using System;
 using System.Collections.Generic;
+using System.Linq;
+using Masuit.Tools.DateTimeExt;
 
 namespace Masuit.Tools.Models;
 
@@ -9,7 +10,7 @@ namespace Masuit.Tools.Models;
 /// </summary>
 public class DateTimeRange : ITimePeriod
 {
-    public DateTimeRange(DateTime start, DateTime end)
+    public DateTimeRange(DateTime? start, DateTime? end)
     {
         if (start > end)
         {
@@ -27,12 +28,12 @@ public class DateTimeRange : ITimePeriod
     /// <summary>
     /// 起始时间
     /// </summary>
-    public DateTime Start { get; set; }
+    public DateTime? Start { get; set; }
 
     /// <summary>
     /// 结束时间
     /// </summary>
-    public DateTime End { get; set; }
+    public DateTime? End { get; set; }
 
     /// <summary>
     /// 是否相交
@@ -40,7 +41,7 @@ public class DateTimeRange : ITimePeriod
     /// <param name="start"></param>
     /// <param name="end"></param>
     /// <returns></returns>
-    public bool HasIntersect(DateTime start, DateTime end)
+    public bool HasIntersect(DateTime? start, DateTime? end)
     {
         return HasIntersect(new DateTimeRange(start, end));
     }
@@ -52,7 +53,7 @@ public class DateTimeRange : ITimePeriod
     /// <returns></returns>
     public bool HasIntersect(DateTimeRange range)
     {
-        return Start.In(range.Start, range.End) || End.In(range.Start, range.End);
+        return IsDatetimeRangeOverlap(Start, End, range.Start, range.End);
     }
 
     /// <summary>
@@ -62,14 +63,14 @@ public class DateTimeRange : ITimePeriod
     /// <returns></returns>
     public (bool intersected, DateTimeRange range) Intersect(DateTimeRange range)
     {
-        if (HasIntersect(range.Start, range.End))
+        if (!HasIntersect(range.Start, range.End))
         {
-            var list = new List<DateTime>() { Start, range.Start, End, range.End };
-            list.Sort();
-            return (true, new DateTimeRange(list[1], list[2]));
+            return (false, null);
         }
 
-        return (false, null);
+        var list = new HashSet<DateTime?> { Start, range.Start, End, range.End }.ToList();
+        list.Sort();
+        return (true, new DateTimeRange(list[1], list[2]));
     }
 
     /// <summary>
@@ -90,7 +91,7 @@ public class DateTimeRange : ITimePeriod
     /// <returns></returns>
     public bool Contains(DateTimeRange range)
     {
-        return range.Start.In(Start, End) && range.End.In(Start, End);
+        return IsDatetimeRangeOverlap(Start, End, range.Start, range.End);
     }
 
     /// <summary>
@@ -99,7 +100,7 @@ public class DateTimeRange : ITimePeriod
     /// <param name="start"></param>
     /// <param name="end"></param>
     /// <returns></returns>
-    public bool Contains(DateTime start, DateTime end)
+    public bool Contains(DateTime? start, DateTime? end)
     {
         return Contains(new DateTimeRange(start, end));
     }
@@ -111,7 +112,7 @@ public class DateTimeRange : ITimePeriod
     /// <returns></returns>
     public bool In(DateTimeRange range)
     {
-        return Start.In(range.Start, range.End) && End.In(range.Start, range.End);
+        return IsDatetimeRangeOverlap(Start, End, range.Start, range.End);
     }
 
     /// <summary>
@@ -132,14 +133,11 @@ public class DateTimeRange : ITimePeriod
     /// <returns></returns>
     public DateTimeRange Union(DateTimeRange range)
     {
-        if (HasIntersect(range))
-        {
-            var list = new List<DateTime>() { Start, range.Start, End, range.End };
-            list.Sort();
-            return new DateTimeRange(list[0], list[3]);
-        }
-
-        throw new Exception("不相交的时间段不能合并");
+        if (!HasIntersect(range))
+            throw new Exception("不相交的时间段不能合并");
+        var list = new HashSet<DateTime?> { Start, range.Start, End, range.End }.ToList();
+        list.Sort();
+        return new DateTimeRange(list[0], list[3]);
     }
 
     /// <summary>
@@ -164,9 +162,14 @@ public class DateTimeRange : ITimePeriod
     {
         if (obj is DateTimeRange range)
         {
-            return Start.Date == range.Start.Date && End.Date == range.End.Date;
+            return Start?.Date == range.Start?.Date && End?.Date == range.End?.Date;
         }
 
         return false;
     }
+
+    private static bool IsDatetimeRangeOverlap(DateTime? startDateA, DateTime? endDateA, DateTime? startDateB, DateTime? endDateB)
+    {
+        return !(endDateA < startDateB || endDateB < startDateA);
+    }
 }

+ 2 - 2
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -55,12 +55,12 @@
         <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="[3.1.32]" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net9'">
-        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.8" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.9" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net6'">
         <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.36" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net8'">
-        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.19" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.20" />
     </ItemGroup>
 </Project>

+ 2 - 2
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -45,13 +45,13 @@ github:https://github.com/ldqk/Masuit.Tools
         <PackageReference Include="Microsoft.EntityFrameworkCore" Version="[3.1.32]" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net9'">
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.8" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.9" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net6'">
         <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.36" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net8'">
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.19" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.20" />
     </ItemGroup>
     <ItemGroup>
       <Compile Remove="..\Masuit.Tools.Abstractions\Mapping\**" />

+ 1 - 1
Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

@@ -37,7 +37,7 @@
       </None>
     </ItemGroup>
     <ItemGroup>
-        <PackageReference Include="EPPlus" Version="8.1.0" />
+        <PackageReference Include="EPPlus" Version="8.1.1" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
     </ItemGroup>
     <ItemGroup>

+ 1 - 1
Masuit.Tools.Net45/Masuit.Tools.Net45.csproj

@@ -38,7 +38,7 @@
         <PackageReference Include="DnsClient" Version="[1.7.0]" />
         <PackageReference Include="Microsoft.AspNet.Mvc" Version="5.3.0" />
         <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
-        <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
+        <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
         <PackageReference Include="System.ValueTuple" version="[4.5.0]" />
         <Reference Include="System.ComponentModel.DataAnnotations" />
         <Reference Include="System.Web" />

+ 1 - 1
Masuit.Tools.NoSQL.MongoDBClient/Masuit.Tools.NoSQL.MongoDBClient.csproj

@@ -38,7 +38,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="MongoDB.Driver" Version="3.4.3" />
+    <PackageReference Include="MongoDB.Driver" Version="3.5.0" />
   </ItemGroup>
 
 </Project>

+ 1 - 1
Masuit.Tools/Masuit.Tools.Net.csproj

@@ -35,7 +35,7 @@
 
     <ItemGroup>
         <PackageReference Include="Microsoft.AspNet.Mvc" Version="5.3.0" />
-        <PackageReference Include="StackExchange.Redis" Version="2.9.11" />
+        <PackageReference Include="StackExchange.Redis" Version="2.9.17" />
         <ProjectReference Include="..\Masuit.Tools.Abstractions\Masuit.Tools.Abstractions.csproj" />
         <Reference Include="System.Web" />
     </ItemGroup>

+ 167 - 0
Test/Masuit.Tools.Abstractions.Test/DateTimeExt/DateTimeRangeTest.cs

@@ -0,0 +1,167 @@
+using System;
+using Masuit.Tools.Models;
+using Xunit;
+
+namespace Masuit.Tools.Abstractions.Test.DateTimeExt;
+
+public class DateTimeRangeTest
+{
+    [Fact]
+    public void Constructor_WithValidDates_ShouldCreateInstance()
+    {
+        var start = new DateTime(2025, 1, 1);
+        var end = new DateTime(2025, 1, 10);
+        var range = new DateTimeRange(start, end);
+        Assert.Equal(start, range.Start);
+        Assert.Equal(end, range.End);
+    }
+
+    [Fact]
+    public void Constructor_StartAfterEnd_ShouldThrowException()
+    {
+        var start = new DateTime(2025, 1, 10);
+        var end = new DateTime(2025, 1, 1);
+        Assert.Throws<Exception>(() => new DateTimeRange(start, end));
+    }
+
+    [Fact]
+    public void ParameterlessConstructor_ShouldCreateInstanceWithNulls()
+    {
+        var range = new DateTimeRange();
+        Assert.Null(range.Start);
+        Assert.Null(range.End);
+    }
+
+    [Theory]
+    [InlineData("2025-01-05", "2025-01-15", "2025-01-10", "2025-01-20", true)] // Overlap
+    [InlineData("2025-01-05", "2025-01-15", "2025-01-15", "2025-01-20", true)] // Touch at end
+    [InlineData("2025-01-05", "2025-01-15", "2025-01-01", "2025-01-05", true)] // Touch at start
+    [InlineData("2025-01-05", "2025-01-15", "2025-01-20", "2025-01-25", false)] // No overlap
+    [InlineData("2025-01-01", "2025-01-31", "2025-01-10", "2025-01-20", true)] // Contain
+    [InlineData("2025-01-10", "2025-01-20", "2025-01-01", "2025-01-31", true)] // Inside
+    public void HasIntersect_ShouldReturnCorrectly(string s1, string e1, string s2, string e2, bool expected)
+    {
+        var range1 = new DateTimeRange(DateTime.Parse(s1), DateTime.Parse(e1));
+        var range2 = new DateTimeRange(DateTime.Parse(s2), DateTime.Parse(e2));
+        Assert.Equal(expected, range1.HasIntersect(range2));
+    }
+
+    [Fact]
+    public void Intersect_WithOverlappingRanges_ShouldReturnIntersection()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 5), new DateTime(2025, 1, 15));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 10), new DateTime(2025, 1, 20));
+        var (intersected, range) = range1.Intersect(range2);
+        Assert.True(intersected);
+        Assert.Equal(new DateTime(2025, 1, 10), range.Start);
+        Assert.Equal(new DateTime(2025, 1, 15), range.End);
+    }
+
+    [Fact]
+    public void Intersect_WithNonOverlappingRanges_ShouldReturnFalse()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 5), new DateTime(2025, 1, 15));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 20), new DateTime(2025, 1, 25));
+        var (intersected, range) = range1.Intersect(range2);
+        Assert.False(intersected);
+        Assert.Null(range);
+    }
+
+    [Fact]
+    public void Contains_WithOverlappingRange_ShouldReturnTrue_DueToIncorrectImplementation()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 20));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 15), new DateTime(2025, 1, 25));
+        Assert.True(range1.Contains(range2));
+    }
+
+    [Fact]
+    public void Contains_WithInnerRange_ShouldReturnTrue()
+    {
+        var outer = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 31));
+        var inner = new DateTimeRange(new DateTime(2025, 1, 10), new DateTime(2025, 1, 20));
+        Assert.True(outer.Contains(inner));
+    }
+
+    [Fact]
+    public void In_WithOuterRange_ShouldReturnTrue()
+    {
+        var inner = new DateTimeRange(new DateTime(2025, 1, 10), new DateTime(2025, 1, 20));
+        var outer = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 31));
+        Assert.True(inner.In(outer));
+    }
+
+    [Fact]
+    public void In_WithOverlappingRange_ShouldReturnTrue_DueToIncorrectImplementation()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 15), new DateTime(2025, 1, 25));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 20));
+        Assert.True(range1.In(range2));
+    }
+
+    [Fact]
+    public void Union_WithOverlappingRanges_ShouldReturnCombinedRange()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 5), new DateTime(2025, 1, 15));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 10), new DateTime(2025, 1, 20));
+        var union = range1.Union(range2);
+        Assert.Equal(new DateTime(2025, 1, 5), union.Start);
+        Assert.Equal(new DateTime(2025, 1, 20), union.End);
+    }
+
+    [Fact]
+    public void Union_WithNonOverlappingRanges_ShouldThrowException()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 5), new DateTime(2025, 1, 15));
+        var range2 = new DateTimeRange(new DateTime(2025, 1, 20), new DateTime(2025, 1, 25));
+        Assert.Throws<Exception>(() => range1.Union(range2));
+    }
+
+    [Fact]
+    public void ToString_ShouldReturnFormattedString()
+    {
+        var start = new DateTime(2025, 1, 1, 10, 30, 0);
+        var end = new DateTime(2025, 1, 10, 18, 45, 0);
+        var range = new DateTimeRange(start, end);
+        var expected = "2025-01-01 10:30:00~2025-01-10 18:45:00";
+        Assert.Equal(expected, range.ToString());
+    }
+
+    [Fact]
+    public void Equals_WithSameDatesAndTimes_ShouldReturnTrue()
+    {
+        var start = new DateTime(2025, 1, 1, 10, 0, 0);
+        var end = new DateTime(2025, 1, 10, 20, 0, 0);
+        var range1 = new DateTimeRange(start, end);
+        var range2 = new DateTimeRange(start, end);
+        Assert.True(range1.Equals(range2));
+    }
+
+    [Fact]
+    public void Equals_WithSameDatesDifferentTimes_ShouldReturnTrue_DueToDateOnlyComparison()
+    {
+        var start1 = new DateTime(2025, 1, 1, 10, 0, 0);
+        var end1 = new DateTime(2025, 1, 10, 20, 0, 0);
+        var start2 = new DateTime(2025, 1, 1, 12, 0, 0);
+        var end2 = new DateTime(2025, 1, 10, 22, 0, 0);
+        var range1 = new DateTimeRange(start1, end1);
+        var range2 = new DateTimeRange(start2, end2);
+        Assert.True(range1.Equals(range2));
+    }
+
+    [Fact]
+    public void Equals_WithDifferentDates_ShouldReturnFalse()
+    {
+        var range1 = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 10));
+        var range2 = new DateTimeRange(new DateTime(2025, 2, 1), new DateTime(2025, 2, 10));
+        Assert.False(range1.Equals(range2));
+    }
+
+    [Fact]
+    public void Equals_WithDifferentObject_ShouldReturnFalse()
+    {
+        var range = new DateTimeRange(new DateTime(2025, 1, 1), new DateTime(2025, 1, 10));
+        var other = new object();
+        Assert.False(range.Equals(other));
+    }
+}

+ 3 - 3
Test/Masuit.Tools.Core.Test/Masuit.Tools.Core.Test.csproj

@@ -9,9 +9,9 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="9.0.8" />
-    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.8" />
-    <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
+    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="9.0.9" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.9" />
+    <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.9" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
     <PackageReference Include="xunit" Version="2.9.3" />
     <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">

+ 1 - 1
Test/Masuit.Tools.Test/Masuit.Tools.Test.csproj

@@ -94,7 +94,7 @@
       <Version>4.20.72</Version>
     </PackageReference>
     <PackageReference Include="StackExchange.Redis">
-      <Version>2.9.11</Version>
+      <Version>2.9.17</Version>
     </PackageReference>
     <PackageReference Include="System.Runtime.CompilerServices.Unsafe">
       <Version>6.1.2</Version>