Skip to content

Commit 6dfe3f7

Browse files
authored
Upgrade to LanguageExt v5 (beta) (#54)
Upgrades Dbosoft.Functional from LanguageExt v4 (4.4.2) to v5 (5.0.0-beta-77), including a comprehensive compatibility shim layer to ease migration for downstream consumers. This is a major version bump with significant breaking changes in LanguageExt itself.
1 parent a3d639b commit 6dfe3f7

43 files changed

Lines changed: 2547 additions & 117 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,6 @@ paket-files/
258258

259259
# Python Tools for Visual Studio (PTVS)
260260
__pycache__/
261-
*.pyc
261+
*.pyc
262+
.claude
263+
.mcp-debug-tools/config.json

Dbosoft.Functional.sln

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,89 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dbosoft.Functional.Json", "
1111
EndProject
1212
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dbosoft.Functional.Json.Tests", "test\Dbosoft.Functional.Json.Tests\Dbosoft.Functional.Json.Tests.csproj", "{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}"
1313
EndProject
14+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0C88DD14-F956-CE84-757C-A364CCF449FC}"
15+
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AwesomeAssertions.LanguageExt", "test\AwesomeAssertions.LanguageExt\AwesomeAssertions.LanguageExt.csproj", "{613F443F-D863-4C96-A0B6-CE343C05C2CB}"
17+
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
19+
EndProject
1420
Global
1521
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1622
Debug|Any CPU = Debug|Any CPU
23+
Debug|x64 = Debug|x64
24+
Debug|x86 = Debug|x86
1725
Release|Any CPU = Release|Any CPU
26+
Release|x64 = Release|x64
27+
Release|x86 = Release|x86
1828
EndGlobalSection
1929
GlobalSection(ProjectConfigurationPlatforms) = postSolution
2030
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2131
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|x64.ActiveCfg = Debug|Any CPU
33+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|x64.Build.0 = Debug|Any CPU
34+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|x86.ActiveCfg = Debug|Any CPU
35+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Debug|x86.Build.0 = Debug|Any CPU
2236
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|Any CPU.ActiveCfg = Release|Any CPU
2337
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|x64.ActiveCfg = Release|Any CPU
39+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|x64.Build.0 = Release|Any CPU
40+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|x86.ActiveCfg = Release|Any CPU
41+
{D38F1C28-A069-4E32-81FA-1F3F1C7F3619}.Release|x86.Build.0 = Release|Any CPU
2442
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2543
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|x64.ActiveCfg = Debug|Any CPU
45+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|x64.Build.0 = Debug|Any CPU
46+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|x86.ActiveCfg = Debug|Any CPU
47+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Debug|x86.Build.0 = Debug|Any CPU
2648
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|Any CPU.ActiveCfg = Release|Any CPU
2749
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|Any CPU.Build.0 = Release|Any CPU
50+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|x64.ActiveCfg = Release|Any CPU
51+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|x64.Build.0 = Release|Any CPU
52+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|x86.ActiveCfg = Release|Any CPU
53+
{ADA73324-0DE5-479D-A63B-888EB922984E}.Release|x86.Build.0 = Release|Any CPU
2854
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2955
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
56+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|x64.ActiveCfg = Debug|Any CPU
57+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|x64.Build.0 = Debug|Any CPU
58+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|x86.ActiveCfg = Debug|Any CPU
59+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Debug|x86.Build.0 = Debug|Any CPU
3060
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
3161
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|Any CPU.Build.0 = Release|Any CPU
62+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|x64.ActiveCfg = Release|Any CPU
63+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|x64.Build.0 = Release|Any CPU
64+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|x86.ActiveCfg = Release|Any CPU
65+
{1060C36D-CF26-4932-A9E6-F2C5BC32B8B7}.Release|x86.Build.0 = Release|Any CPU
3266
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3367
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
68+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|x64.ActiveCfg = Debug|Any CPU
69+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|x64.Build.0 = Debug|Any CPU
70+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|x86.ActiveCfg = Debug|Any CPU
71+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Debug|x86.Build.0 = Debug|Any CPU
3472
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
3573
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|Any CPU.Build.0 = Release|Any CPU
74+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|x64.ActiveCfg = Release|Any CPU
75+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|x64.Build.0 = Release|Any CPU
76+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|x86.ActiveCfg = Release|Any CPU
77+
{E6E91D63-DB2C-4B6F-A701-4F1BA558AB0F}.Release|x86.Build.0 = Release|Any CPU
78+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
79+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
80+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|x64.ActiveCfg = Debug|Any CPU
81+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|x64.Build.0 = Debug|Any CPU
82+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|x86.ActiveCfg = Debug|Any CPU
83+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Debug|x86.Build.0 = Debug|Any CPU
84+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
85+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|Any CPU.Build.0 = Release|Any CPU
86+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|x64.ActiveCfg = Release|Any CPU
87+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|x64.Build.0 = Release|Any CPU
88+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|x86.ActiveCfg = Release|Any CPU
89+
{613F443F-D863-4C96-A0B6-CE343C05C2CB}.Release|x86.Build.0 = Release|Any CPU
3690
EndGlobalSection
3791
GlobalSection(SolutionProperties) = preSolution
3892
HideSolutionNode = FALSE
3993
EndGlobalSection
94+
GlobalSection(NestedProjects) = preSolution
95+
{613F443F-D863-4C96-A0B6-CE343C05C2CB} = {0C88DD14-F956-CE84-757C-A364CCF449FC}
96+
EndGlobalSection
4097
GlobalSection(ExtensibilityGlobals) = postSolution
4198
SolutionGuid = {B7150D06-C3F8-4A71-B3C2-FA23C59EBAED}
4299
EndGlobalSection

MIGRATION-v5.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# LanguageExt v5 Migration Analysis
2+
3+
Analysis of breaking changes when upgrading Dbosoft.Functional from LanguageExt v4 (`[4.4.0,4.5.0)`) to v5 (`5.0.0-beta-77`).
4+
5+
> Target framework also changes: `netstandard2.0` -> `net10.0` (v5 requires .NET 10+)
6+
7+
---
8+
9+
## Build Result: 18 errors, 4 warnings
10+
11+
---
12+
13+
## Breaking Changes in LanguageExt v5
14+
15+
### 1. Removed Types
16+
17+
| Removed | Replacement |
18+
|---------|-------------|
19+
| `EitherAsync<L, R>` | `EitherT<L, IO, R>` (monad transformer over IO) |
20+
| `OptionAsync<A>` | `OptionT<IO, A>` |
21+
| `TryAsync<A>` | `TryT<IO, A>` |
22+
| `TryOption<A>` | `OptionT<Try, A>` |
23+
| `Aff<A>`, `Aff<RT, A>` | `Eff<A>` (now handles both sync and async) |
24+
| `NewType<NEWTYPE, A, PRED, ORD>` | C# `record` types (NewType removed entirely) |
25+
| `Pred<A>`, `True<A>` | Removed (predicate system) |
26+
27+
### 2. Removed Namespaces / Type Classes
28+
29+
| Removed | Replacement |
30+
|---------|-------------|
31+
| `LanguageExt.ClassInstances.Pred` | Removed |
32+
| `LanguageExt.TypeClasses` | `LanguageExt.Traits` (static abstract interface members) |
33+
| `struct, Ord<A>` constraint | `Ord<A>` is now a trait interface, not a struct type class |
34+
35+
### 3. Removed Prelude Functions
36+
37+
| Removed | Replacement |
38+
|---------|-------------|
39+
| `Prelude.RightAsync<L, R>(x)` | `EitherT<L, IO, R>.Right(x)` or `Pure(x)` |
40+
| `Prelude.LeftAsync<L, R>(x)` | `EitherT<L, IO, R>.Left(x)` or `Fail(x)` |
41+
| `Prelude.SomeAsync(x)` | `OptionT<IO, A>.Some(x)` |
42+
| `x.ToAsync()` (on Either/Option) | Wrap in transformer: `EitherT.lift(io)` |
43+
44+
### 4. Effect System Changes
45+
46+
- `Aff<A>` merged into `Eff<A>` (which now supports both sync and async)
47+
- `Eff<RT, A>` no longer requires `HasCancel<RT>` trait
48+
- New `IO<A>` monad is the foundation for all side effects
49+
- `liftIO(async () => ...)` and `liftEff(async () => ...)` for async lifting
50+
51+
### 5. Validation Changes
52+
53+
- `Validation` `|` operator semantics changed (v4 `|` behaved like `&`)
54+
- `ValidationT<F, M, A>` monad transformer added
55+
56+
### 6. Either `bi` Functions
57+
58+
- Arguments to `BiMap`, `BiFold`, etc. are **flipped** (Left/Right handler order swapped)
59+
60+
### 7. Semigroup / Monoid
61+
62+
- Now traits that types must implement directly (static abstract `operator+` and `Empty`)
63+
- Cannot make external types into semigroups/monoids anymore
64+
65+
### 8. Transformers Package Removed
66+
67+
- `LanguageExt.Transformers` deleted (500k+ lines of generated `MapT`, `BindT`, etc.)
68+
- Replaced by generic trait-based methods in `LanguageExt.Core`
69+
70+
---
71+
72+
## Impact on Dbosoft.Functional Source Files
73+
74+
### `EitherExtensions.cs` — 6 errors
75+
76+
All methods using `EitherAsync<,>` are broken:
77+
78+
| Method | Issue | Migration Path |
79+
|--------|-------|----------------|
80+
| `ToEitherRight<TIn>(this TIn)` | Uses `Prelude.RightAsync` (removed) | Return `Either<Error, TIn>` synchronously, or use `EitherT` |
81+
| `ToEitherLeft<TIn>(this Error)` | Uses `Prelude.LeftAsync` (removed) | Return `Either<Error, TIn>` synchronously, or use `EitherT` |
82+
| `IfNoneAsync<TIn>(...)` | Uses `.ToAsync()` (removed) | Rewrite using `Either` + `Eff`/`IO` for async |
83+
| `NoneToError<T>(this EitherAsync<Error, Option<T>>, Error)` | `EitherAsync` removed | Rewrite for `EitherT<Error, IO, Option<T>>` or `Eff<Either<Error, T>>` |
84+
| `SomeToError<T>(...)` (both overloads) | `EitherAsync` removed | Same as NoneToError |
85+
86+
### `AffExtensions.cs` — 3 errors
87+
88+
| Method | Issue | Migration Path |
89+
|--------|-------|----------------|
90+
| `ToAff<R>(this EitherAsync<Error, R>)` | Both `Aff` and `EitherAsync` removed | **Delete entirely** — no direct equivalent needed |
91+
| `ToEitherAsync<R>(this ValueTask<Fin<R>>)` | `EitherAsync` removed | Convert to `Either<Error, R>` from `Fin<R>` (sync), or wrap in `IO`/`Eff` |
92+
93+
### `UseExtensions.cs` — 4 errors
94+
95+
| Method | Issue | Migration Path |
96+
|--------|-------|----------------|
97+
| `Use<L,R1,R2>(this EitherAsync<L,R1>, ...)` | `EitherAsync` removed | Rewrite for `EitherT<L, IO, R1>` or drop in favor of `Eff` resource tracking |
98+
| `Use<L,R1,R2>(this Task<Either<L,R1>>, ...)` | Still compiles (uses `Task<Either>`) | **Keep** — may still work |
99+
| `Use<L,R1,R2>(this Either<L,R1>, ...)` | Still compiles | **Keep** |
100+
101+
> Note: v5 `Eff<A>` has built-in resource tracking with automatic cleanup, which may make `Use` extensions redundant.
102+
103+
### `ValidatingNewType.cs` — 5 errors
104+
105+
| Issue | Detail |
106+
|-------|--------|
107+
| `LanguageExt.ClassInstances.Pred` removed | Entire predicate system gone |
108+
| `LanguageExt.TypeClasses` removed | Replaced by `LanguageExt.Traits` |
109+
| `NewType<NEWTYPE, A, True<A>, ORD>` removed | `NewType` with 4 generic args no longer exists |
110+
| `True<A>` removed | Predicate class gone |
111+
| `struct, Ord<A>` constraint invalid | `Ord<A>` is now a trait, not a struct |
112+
113+
**Migration:** `NewType` is replaced by C# `record` types in v5. The entire `ValidatingNewType` class needs a ground-up redesign — likely as an abstract `record` with a static `Validate` method returning `Validation<Error, NEWTYPE>`.
114+
115+
### `ErrorExtensions.cs` — 0 errors
116+
117+
`Error` type changed from struct to abstract record, but the `Print` method's pattern matching on `ManyErrors` / `Exceptional` should still work since those subtypes exist in v5. **Likely still compiles** but needs verification.
118+
119+
---
120+
121+
## Impact on Dbosoft.Functional.Json
122+
123+
### `NewTypeJsonConverter.cs` — Multiple errors expected
124+
125+
The entire converter depends on `NewType<NEWTYPE, A, PRED, ORD>` which no longer exists in v5. Also uses:
126+
- `Pred<A>` (removed)
127+
- `Ord<A>` as struct constraint (changed to trait)
128+
- `NewType<,,,>` reflection checks
129+
130+
**Migration:** Needs complete rewrite. Since v5 replaces `NewType` with plain C# `record` types, the JSON converter concept needs to be reimagined — possibly as a converter for record types that implement a specific interface, or it may become unnecessary if records use standard JSON serialization.
131+
132+
---
133+
134+
## Impact on Tests
135+
136+
### `FluentAssertions.LanguageExt` — Incompatible
137+
138+
Package `0.5.0` targets LanguageExt v4. Will not work with v5 types. Need to either:
139+
- Find/create a v5-compatible assertion library
140+
- Write custom assertion extensions (like the `AwesomeAssertions.LanguageExt` in SAP2Dynamics)
141+
142+
### Test code using `EitherAsync`, `RightAsync`, `LeftAsync`, `Aff`
143+
144+
All test methods using these types/functions need rewriting.
145+
146+
---
147+
148+
## Decision Points
149+
150+
1. **`EitherAsync` replacement strategy**: Use `EitherT<L, IO, R>` everywhere, or switch to `Eff<Either<L, R>>`/`Eff<R>` with error handling?
151+
2. **`ValidatingNewType` redesign**: Keep the concept with records, or drop it in favor of simple record + static validation?
152+
3. **`NewTypeJsonConverter` redesign**: Rewrite for records, or drop if no longer needed?
153+
4. **`UseExtensions` for `EitherAsync`**: Drop the `EitherAsync` overload, or rewrite for `EitherT`? (v5 `Eff` has built-in resource tracking)
154+
5. **`AffExtensions`**: Delete entirely since both `Aff` and `EitherAsync` are gone?
155+
6. **Test assertion library**: Write custom v5 assertions or wait for community package?

_inspect/Program.cs

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
using System;
2+
using System.Linq;
3+
using System.Reflection;
4+
5+
// ===== V4 =====
6+
Console.WriteLine("##################################################");
7+
Console.WriteLine("# LanguageExt.Core v4.4.9 - NewType types");
8+
Console.WriteLine("##################################################");
9+
var dllV4 = @"p:\packages\.nuget\languageext.core\4.4.9\lib\net7.0\LanguageExt.Core.dll";
10+
try
11+
{
12+
// Need to use MetadataLoadContext since we can't load both versions
13+
var resolver = new PathAssemblyResolver(new string[] {
14+
dllV4,
15+
typeof(object).Assembly.Location,
16+
System.IO.Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "System.Runtime.dll")
17+
});
18+
using var mlc = new MetadataLoadContext(resolver);
19+
var asmV4 = mlc.LoadFromAssemblyPath(dllV4);
20+
21+
var ntTypes = asmV4.GetTypes().Where(t => t.Name.Contains("NewType") && !t.Name.Contains("<")).OrderBy(t => t.FullName).ToArray();
22+
foreach (var t in ntTypes)
23+
{
24+
Console.WriteLine($"\nType: {t.FullName}");
25+
Console.WriteLine($" GenericArgs: {string.Join(", ", t.GetGenericArguments().Select(g => g.Name))}");
26+
Console.WriteLine($" IsAbstract={t.IsAbstract} IsClass={t.IsClass}");
27+
if (t.BaseType != null)
28+
Console.WriteLine($" BaseType: {t.BaseType}");
29+
30+
Console.WriteLine(" Properties:");
31+
foreach (var p in t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
32+
{
33+
Console.WriteLine($" {p.PropertyType} {p.Name}");
34+
}
35+
36+
Console.WriteLine(" Methods (declared):");
37+
foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
38+
{
39+
if (m.IsSpecialName) continue;
40+
var parms = string.Join(", ", m.GetParameters().Select(p => $"{p.ParameterType} {p.Name}"));
41+
var access = m.IsPublic ? "public" : m.IsFamily ? "protected" : "private";
42+
var stat = m.IsStatic ? " static" : "";
43+
Console.WriteLine($" {access}{stat} {m.ReturnType} {m.Name}({parms})");
44+
}
45+
}
46+
}
47+
catch (Exception ex)
48+
{
49+
Console.WriteLine($"Error loading v4: {ex.Message}");
50+
}
51+
52+
// ===== V5 - more detail =====
53+
Console.WriteLine("\n\n##################################################");
54+
Console.WriteLine("# LanguageExt.Core v5.0.0-beta-77 - New interface details");
55+
Console.WriteLine("##################################################");
56+
57+
var dllV5 = @"p:\packages\.nuget\languageext.core\5.0.0-beta-77\lib\net10.0\LanguageExt.Core.dll";
58+
var asmV5 = System.Reflection.Assembly.LoadFrom(dllV5);
59+
60+
// Check if there is a NewTry or Value property anywhere
61+
Console.WriteLine("\n=== Searching for 'NewTry' in all type members ===");
62+
foreach (var t in asmV5.GetTypes().Where(t => !t.Name.Contains("<")))
63+
{
64+
var methods = t.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly)
65+
.Where(m => m.Name.Contains("NewTry")).ToArray();
66+
if (methods.Length > 0)
67+
{
68+
Console.WriteLine($" Type: {t.FullName}");
69+
foreach (var m in methods)
70+
Console.WriteLine($" {m.ReturnType.Name} {m.Name}({string.Join(", ", m.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})");
71+
}
72+
}
73+
74+
// Check the Identifier type if it exists
75+
Console.WriteLine("\n=== Searching for 'Identifier' types ===");
76+
foreach (var t in asmV5.GetTypes().Where(t => t.Name.Contains("Identifier") && !t.Name.Contains("<")).Take(10))
77+
{
78+
Console.WriteLine($" {t.FullName}");
79+
}
80+
81+
// Check for NumType, FloatType
82+
Console.WriteLine("\n=== Searching for 'NumType' or 'FloatType' ===");
83+
foreach (var t in asmV5.GetTypes().Where(t => (t.Name.Contains("NumType") || t.Name.Contains("FloatType")) && !t.Name.Contains("<")).Take(10))
84+
{
85+
Console.WriteLine($" {t.FullName}");
86+
}
87+
88+
// Check the DomainType interface more - how is it meant to be used?
89+
// Also check if Fin is still there
90+
Console.WriteLine("\n=== DomainType`2 deeper look ===");
91+
var dt2 = asmV5.GetTypes().First(t => t.Name == "DomainType`2");
92+
Console.WriteLine($" Full: {dt2}");
93+
Console.WriteLine($" All interfaces (including inherited):");
94+
foreach (var i in dt2.GetInterfaces())
95+
Console.WriteLine($" {i}");
96+
97+
Console.WriteLine("\n=== Checking for Locus/Identifier types (DomainType implementations) ===");
98+
var domainImpls = asmV5.GetTypes().Where(t =>
99+
{
100+
try
101+
{
102+
return t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition().Name == "DomainType`2");
103+
}
104+
catch { return false; }
105+
}).Take(20).ToArray();
106+
foreach (var t in domainImpls)
107+
{
108+
Console.WriteLine($" {t.FullName} (GenArgs={t.GetGenericArguments().Length})");
109+
}
110+
111+
// Check Fin
112+
Console.WriteLine("\n=== Fin`1 detail ===");
113+
var fin = asmV5.GetTypes().First(t => t.FullName == "LanguageExt.Fin`1");
114+
Console.WriteLine($" {fin.FullName} IsAbstract={fin.IsAbstract} IsClass={fin.IsClass}");

_inspect/_inspect.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net10.0</TargetFramework>
5+
</PropertyGroup>
6+
</Project>

src/Dbosoft.Functional.Json/DataTypes/NewTypeJsonConverter.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
using System;
1+
using System;
22
using System.Text.Json;
33
using System.Text.Json.Serialization;
44
using LanguageExt;
55
using LanguageExt.TypeClasses;
66

77
namespace Dbosoft.Functional.Json.DataTypes;
88

9+
#pragma warning disable CS0618 // Obsolete shim types
10+
911
/// <summary>
1012
/// <para>
1113
/// A JSON converter which supports <see cref="NewType{NEWTYPE,A, PRED, ORD}"/>.
@@ -189,3 +191,5 @@ public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions
189191
}
190192
}
191193
}
194+
195+
#pragma warning restore CS0618

0 commit comments

Comments
 (0)