Stroniax
Stroniax
CC#
Created by Stroniax on 1/27/2024 in #help
Builder Pattern as Ref Struct
Hey all, I'm trying to make a source-generated builder which I want to be a struct. I'm running into a problem when trying to chain the entire build, but if I capture the builder in a variable first I can chain it as much as I like. Wondering if there's any language feature/etc that would help me out here? What I'd like is to use the same builder struct instance and not have to copy it with each chained method.
C#
public struct MyBuilder {
public required int Id { get; set; }
public string? Name { get; set; }
public My Build() => new(this);
}
public static class MyBuilderExtensions {
public ref MyBuilder WithId(this ref MyBuilder b, int id) {
b.Id = id;
return ref b;
}
public ref MyBuilder WithName(this ref MyBuilder b, string? name) {
b.Name = name;
return ref b;
}
}
public static class Usage {
public static My Works() {
var builder = new MyBuilder() { Id = 1 };
return builder.WithName("Test").Build();
}
public static My DoesNotWork() {
// CS1510: A ref or out value must be an assignable variable
return new MyBuilder() { Id = 1 }.WithName("Test").Build();
}
}
public partial class My
{
public required int Id { get => throw null; init => throw null; }
public string Name { get => throw null; init => throw null; }
// only if set by builder/init
public bool TryGetName(out string name) => throw null;;
[SetsRequiredMembers]
public My(int id) => throw null;
[SetsRequiredMembers]
public My(MyBuilder b) => throw null;
}
C#
public struct MyBuilder {
public required int Id { get; set; }
public string? Name { get; set; }
public My Build() => new(this);
}
public static class MyBuilderExtensions {
public ref MyBuilder WithId(this ref MyBuilder b, int id) {
b.Id = id;
return ref b;
}
public ref MyBuilder WithName(this ref MyBuilder b, string? name) {
b.Name = name;
return ref b;
}
}
public static class Usage {
public static My Works() {
var builder = new MyBuilder() { Id = 1 };
return builder.WithName("Test").Build();
}
public static My DoesNotWork() {
// CS1510: A ref or out value must be an assignable variable
return new MyBuilder() { Id = 1 }.WithName("Test").Build();
}
}
public partial class My
{
public required int Id { get => throw null; init => throw null; }
public string Name { get => throw null; init => throw null; }
// only if set by builder/init
public bool TryGetName(out string name) => throw null;;
[SetsRequiredMembers]
public My(int id) => throw null;
[SetsRequiredMembers]
public My(MyBuilder b) => throw null;
}
EDIT: The problem occurs because the extension method operates on a ref of the instance, so I must have a field/variable declared beforehand of the type. This means I can't just call new().Extension(), as the result of new() must be assigned to something before it can be used. That is what I am trying to resolve.
58 replies
CC#
Created by Stroniax on 2/14/2023 in #help
❔ Non-Dictionary Default Json Converter
I have an interface I have to implement which is derived from IReadOnlyDictionary<,>. This must be implemented by many classes. I don't want to write custom converter logic for all of these types, is there a way to tell the System.Text.Json.JsonSerializer to not use the dictionary converter and instead to use its regular converter logic for these types?
2 replies
CC#
Created by Stroniax on 1/26/2023 in #help
✅ How Does StreamReader.ReadLine Know When to Stop?
I am working with streams and don’t want to grab more data than I need from the stream. I realized somehow a streamreader knows when to stop reading, but I can’t imagine it reads one byte at a time to find the terminator character. How does it know when it has read enough and not consume more of the buffer?
2 replies
CC#
Created by Stroniax on 1/20/2023 in #help
✅ HTTP/3 Server Without AspNetCore
For a work-related project I'm setting up a small local http API that allows applications for IPC or sys admins for troubleshooting to check on an application's state. It only has to have read endpoints for four resources and a POST endpoint for one other. I don't want to bloat the application with the entire AspNetCore suite - and when I tried to just reference the Kestrel library I had compatibility errors, looks like it hasn't been updated to work with later versions of Microsoft.Extensions.Primitives that I'm referencing. (Kestrel also leans heavily on the built-in DI which I don't want to use.) I started going the route of HttpListener, which is missing only a few features I'd like such as a RequestAborted cancellation token when a request is received, and some poor async APIs (e.g. no CancellationToken parameter). However, I was reading recently about HTTP/3 and would like to support that (don't need to worry about prior HTTP versions if I can support HTTP/3). I don't know how I can do that from HttpListener. Is there another well-tested, modern way to host an HTTP API as part of an application, particularly one that supports HTTP/3?
12 replies
CC#
Created by Stroniax on 1/12/2023 in #help
✅ Struct Fields
Is there a reason to mask two values into a single field on a struct, e.g. if I want a struct MyValue with fields ushort A and ushort B, is there any value in having the struct internally store the value as uint _c? I formerly thought since this was one field it was better because everyone says to generally not use a struct with a lot of fields, but based on some reading I have done it seems that maybe this is treated in memory the same way since those two ushort fields are side-by-side and effectively storing two ushort fields would be no different except that I wouldn't have to manually unmask A and B from _c in my getters.
12 replies
CC#
Created by Stroniax on 1/4/2023 in #help
❔ Read Stream to End of Json Object
I am trying to read a stream from the beginning of a json object until the end of a json object, without reading until the end of the stream. This is specifically meant for things like deserializing a TcpClient's NetworkStream where the stream will not close until I have sent a response and the other end closes. Currently, calling JsonSerializer.Deserialize(stream will not return until the other end calls TcpClient.Close() which means I can't get the full request object and therefore can't send a response that the other end is waiting for.
2 replies
CC#
Created by Stroniax on 11/21/2022 in #help
❔ EF Core Sql Server JsonDocument
I am trying to use Entity Framework Core to map and access a json column. With EF 7, I believe that is supported (via the the ToJson(OwnedNavigationBuilder, string) extension method). However, the value is not a consistent schema, so I cannot map a constant type. I want to use JsonDocument but am getting a number of errors, making me wonder if that is actually possible? The only documentation I can find referencing mapping a JsonDocument property is using npgsql, and I don't see any references to JsonDocument in the SQL Server EF core articles I am finding.
2 replies
CC#
Created by Stroniax on 11/10/2022 in #help
dotnet watch run FileNotFoundException (System.Runtime 7.0)
After updating Visual Studio, which installed the .NET 7.0 SDK, I can no longer use dotnet watch run on my project. I have made no other changes (all target frameworks are still 6.0). dotnet run works just fine, but when I use dotnet watch run the solution builds and then fails with the following exception:
dotnet watch 🚀 Started
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
at System.StartupHookProvider.ProcessStartupHooks()

dotnet watch ❌ Exited with error code -532462766
dotnet watch 🚀 Started
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
File name: 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
at System.Reflection.RuntimeAssembly.GetType(QCallAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at System.StartupHookProvider.CallStartupHook(StartupHookNameOrPath startupHook)
at System.StartupHookProvider.ProcessStartupHooks()

dotnet watch ❌ Exited with error code -532462766
I was expecting that the update alone wouldn't break anything, at least until I updated my project(s)... I can't find anything on Google except for creating a global.json file or possibly changing the target framework, which I do not yet want to do because I want to stick with LTS for this project.
2 replies
CC#
Created by Stroniax on 9/30/2022 in #help
Windows Interactive Logon [Answered]
I have been tasked with writing a program that connects to a remote computer and unlocks the workstation (logging in) with credentials supplied by the remote process. The remoting part is not a concern to me, but I am not finding any way to unlock the device programatically. I have looked at advapi32.dll's LogonUser function but I still do not know how to use the token to unlock the workstation. I'm having trouble finding what I want because Google is very over-saturated with content that matches the search terms I'm using because everybody has logon problems, and I'm not sure how to be more specific to Google about what I need.
6 replies
CC#
Created by Stroniax on 9/15/2022 in #help
EF Core SQL Generation with Custom Type [Answered]
I've got a custom type AssetId, which is an AK member of the type Asset.
class Asset {
int Id; // PK
AssetId? AssetId; // AK
}
struct AssetId {
private int _value;
static AssetId Parse(string s);
string ToString();
}
class AssetIdConverter : ValueConverter<AssetId, string> {
AssetIdConverter(): base(e => e.ToString(), e => AssetId.Parse(e), new ConverterMappingHints(size: 8, unicode: false) {}
}

// inside DbContext.ConfigureConventions
builder.DefaultTypeMapping<AssetId>().HasConversion<AssetIdConverter>().IsUnicode(false).HasMaxLength(8).IsFixedLength();
builder.Property<AssetId>().HasConversion<AssetIdConverter>().IsUnicode(false).HasMaxLength(8).IsFixedLength();
class Asset {
int Id; // PK
AssetId? AssetId; // AK
}
struct AssetId {
private int _value;
static AssetId Parse(string s);
string ToString();
}
class AssetIdConverter : ValueConverter<AssetId, string> {
AssetIdConverter(): base(e => e.ToString(), e => AssetId.Parse(e), new ConverterMappingHints(size: 8, unicode: false) {}
}

// inside DbContext.ConfigureConventions
builder.DefaultTypeMapping<AssetId>().HasConversion<AssetIdConverter>().IsUnicode(false).HasMaxLength(8).IsFixedLength();
builder.Property<AssetId>().HasConversion<AssetIdConverter>().IsUnicode(false).HasMaxLength(8).IsFixedLength();
The AssetId type is internally an int, but for a number of reasons including the fact that it logically contains two values, it is stored as char(8) in the db. No matter how I configure this type, it seems querying against it in EF is always generating SQL like the following: CONVERT(Asset.AssetId as NVARCHAR(max)) = N'00-00-00' (where 00-00-00 is an AssetId.ToString()). I do not want to convert the value to NVARCHAR(max) for this. It shouldn't have to change from char(8) at all.
18 replies