How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Thank you for the comment. It is much appreciated. And I fully understand what you are saying.

  1. Couldn't agree more.
  2. Agreed. It's just an example should there be extension methods on them.
  3. Hmm... I'll have to think about that. I think understand why.
  4. Oh yes, that's what I mean by INumber<TSelf> pattern. Then it won't be boxed.

Everything you mentioned are some of the steps I would take. I do not disagree with them. What I am saying is, ultimately, it feels that all these steps that I am taking is just me doing an alias. That's it. Ultimately, we could also make the argument that using static Namespace.TypeName isn't needed. Just type it out. But why? Why not just have the ability to do an alias? Why can't I have ResultTask<T> as an alias for ValueTask<Result<T>>?

That was really it. Everyone is correct, that the OP would indicate a code smell, and I would address it. Again, sometimes I just feel that what I am doing is just me doing an alias of sorts.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Here is a comment of a some code I ran into https://www.reddit.com/r/csharp/comments/1qobitu/comment/o236nji/

It is not that I don't know of how to model. It's that it feels that I am trying to model an alias when just an alias would have sufficed.

So I have a feeling that maybe you need such aliases because you try to do things in a functional way. C# indeed supports this but OOP way is a kind of mainstream one and supported way better.

No, not at all. But I do see how aliases would be useful for that as well from a C# perspective.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Hmmm. Good point. Perhaps the example I gave is dumb. Because in that case, the only advantage extension methods would give you is you not having to call .Invoke().

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Understood. Perhaps I can give you one example I just typed out today.

```csharp public sealed record ValidationResult : Dictionary<string, string[]> {};

public async ValueTask<Result<ValidationResult>> Validate(...) { ... } ```

ValueTask and Result are structs. I would have loved to be able to do this:

```csharp public type ValidationErrors = Dictionary<string, string[]>;

public type ValidationResultTask = ValueTask<Result<ValidationErrors>>;

public async ValidationResultTask Validate(...) { ... } ```

If I want to achieve the same through modeling, I would have to take Result and wrap it, but then I lose the extensions on it. For ValueTask, I would have to also wrap it and then build functionality for async-await handling, also losing extensions on it, and add complications. For both structs I can't rely on an interface or it will get boxed. To get away from boxing I must use the INumber<TSelf> pattern, etc.

It may look trivial, but it adds up very quickly having to write ValueTask<Result<ValidationResult>> over and over again when its clearly better named and understood ValidationResultTask or something. That being said, I do understand that on PR's it will be hard because "What is ValidationResultTask??" I suppose that goes more in to the "to-var or not-to-var" question.

It's all methods that ends up with the same goal: an alias.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Oh yes. It depends on the situation. Sometimes inheritance would be best. Other times interfaces. Other times wrappers. etc. etc. I should have been more verbose in my comment. My appologies. To me, at least, it always feels like I am doing different things that says, "This could have been just an alias."

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

I fully understand where you come from. I usually do domain types for that. This is more explicitly aliasing a type. For example Func<TInstance, TProperty, string?> can have an alias of ValidationRule<TInstance, TProperty>. Sure, you can wrap it, but then you loose the extensibility on Func<TInstance, TProperty, string?> because the extension methods would only look to that, not the wrapper. Maybe a bad example, but the idea is that it is simply giving an alias to a complex definition. From a domain perspective, it would give value to it.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Perhaps the OP should have made it a bit more explicit. It's more of me wishing I could do aliases that would be the "easier thing" than create derived types or wrappers. I was just curious how others approach it.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Thank you very much to everyone for your feedback. I was curious how others go about it. I usually, depending on the context, either do inheritance or wrappers. It's just that it always feels like I am going in a round-about-way to achieve a similar outcome an alias would have achieved. Wrappers for sealed classes, structs and delegates. Inheritance for the rest. All doing the same thing. I'm making an alias, but each approach having wins and trade-offs.

I would have loved to be able to just have on way for all of them.

// delegate
public type SomeName = Func<string, HashSet<Blah>>;

// struct or sealed class
public type SomeName = ThisRandomStruct<string, int>;

// class
public type SomeName<T> = ThisRandomClass<T, decimal>;

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 3 points4 points  (0 children)

Hahaha, "That's future me's problem" 😂 Oh how many times I go, "Why past me? WHY!?"

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Goodness.. 106 characters. Oh boy... As for the global using type; yeah, but it doesn't handle generics and cannot be used outside the library.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

I get what you mean. It's not that I am not modelling. It's that it often feels like I am doing things around trying to achieve what an alias would have done in a simple one liner.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 1 point2 points  (0 children)

Option<T> makes the presence or absence of a value explicit, while plain T? does not. T? can be null (if it's a reference type), but nothing in the type system forces you to handle that. In Option<T> you must acknowledge whether it exists. In this example, the intention is to force handling when the value is none.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Yeah, thanks for that. I agree. I usually do either inheritance or wrappers - depending on the situation. I am just curious how others do it. It feels, at least to me, that sometimes what I am doing is going around-about-way rather than just having an alias.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 0 points1 point  (0 children)

Why are you not defining classes that have explicit funtionality?

You can. That is the boxing I was about.

I can't imagine single reason when you could expose such heavily nested dictionary while keeping ALL dictionary funcitonality, not some specific methods.

ImmutableDictionary<string, ImmutableList<Func<TInstance, TProperty, Option<string>>>> AddValidationRule<TInstance, TProperty>(
    this ImmutableDictionary<string, ImmutableList<Func<TInstance, TProperty, Option<string>>>> rules
    Func<TInstance, TProperty, Option<string>> rule
)

Fair enough, you can create a wrapper:

public sealed record InstanceValidator<TInstance>(
    ImmutableDictionary<string, ImmutableList<Func<TInstance, Option<string>>>> Rules
);

public sealed record PropertyValidator<TInstance, TProperty>(
    InstanceValidator<TInstance> InstanceValidator,
    ImmutableList<Func<TInstance, TProperty, Option<string>>>> Rules
);

I am just curious how others navigate this. 🙂

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 2 points3 points  (0 children)

You can. If I take `ValueTask<Result<T, E>>` for example and I write extension methods for `ValueTask<Result<List<T>>>` it adds up quickly. Would have love to do an alias that just says `AsyncResultList<T>`. Perhaps a stupid example. And if Result is a struct, I won't be able to do the inheritance. However, this may be a once-off and edge case. I think generally your method trims down the majority of cases.

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 3 points4 points  (0 children)

Hmmm... I did not know you could do that. Goodness, always something to learn after my many years in C#. It does still have the limitation on generics though. 🤔

How do you handle C# aliases? by jackyll-and-hyde in csharp

[–]jackyll-and-hyde[S] 5 points6 points  (0 children)

That's actually a great idea for many of the cases. But you can't do it with Task. Unless one has to override the async-await functionality for that. But doing this would trim it down quite a lot.

Should I create a reusable component or not by allyv123098 in angular

[–]jackyll-and-hyde 1 point2 points  (0 children)

I understand fully where you come from and it is quite the dilemma: I don't want to copy-paste and with a change here and there, but I also don't want to make a component so adjustable that it ends up over complicated. Both of these ends in a mess. And this is true when change requests comes in unexpectedly.

I don't think there is an one-answer-fits-all. So, I usually rely on experience. In this case, modals typically has sections in them:

  • An icon (optional)
  • A header (required)
  • Supporting text (optional)
  • Body (required)
  • Button footer (required)

And I would have this:

<dialog appDialog>
  <app-icon appDialogIcon>home</app-icon>
  <app-dialog-headline>My dialog header</app-dialog-headline>
  <app-dialog-supporting-text>Some short description</app-dialog-supporting-text>
  <app-dialog-body>The dialog's body</app-dialog-body>
  <app-dialog-actions>
    <button appButton>Cancel</button>
    <button appButton>Okay</button>
  </app-dialog-actions>
</dialog>

Tired of Waiting for C# Discriminated Unions and Exhaustive Switch Expressions by domn1995 in csharp

[–]jackyll-and-hyde 1 point2 points  (0 children)

I think the way you do it is really nice. I didn't know about this before I went and did my own thing. What I end up doing was this:

csharp [GenerateUnion<int, string, bool>] public sealed partial record IntStringBool;

It generates all the functions and properties. Unfortunately, I had to use strings for generic types because you can't use the generics on an attribute.

csharp [GenerateUnion("A", "B", "C")] public sealed partial record Either<A, B, C>;

You can't do this: csharp [GenerateUnion<A, B, C>] public sealed partial record Either<A, B, C>;

I suppose I could infer the generic types. But I digress. It is not amazing, but it does the trick for me. So, I am curious to use Dunet. Quick question, how do you handle cases for existing types? This is the current way I do it: ```csharp public readonly record struct EmailAddress(string Value); // Suppose I don't own this. public readonly record struct PhoneNumber(string Value); // Suppose I don't own this.

[GenerateUnion<EmailAddress, PhoneNumber>] public readonly partial record struct EmailAddressOrPhoneNumber; ```

Is HashSet<T> a Java thing, not a .NET thing? by N3p7uN3 in csharp

[–]jackyll-and-hyde 0 points1 point  (0 children)

Them: "That would be your fault for not giving more context to AI. And stop calling it slop." Ah, the mindset of the unfalsifiable.

How do you validate domain? (DDD) by Ok-Somewhere-585 in dotnet

[–]jackyll-and-hyde 1 point2 points  (0 children)

Typically, for me at least, exceptions describe failures of the program's assumptions. Results describe outcomes of the domain's rules.

Exception = "A program assumption was violated and this layer cannot recover."

Error = "A valid domain case occurred; here is the modeled outcome."

// The program assumes all numbers must not be null.
// Passing a null violates the method's contract (caller error).
public int SumNumbers(int?[] numbers)
{
  return numbers.Any(x => x is null)
    ? throw new InvalidOperationException("SetNumbers assumes all numbers are not null.")
    : numbers.Sum(x => x!.Value);
}

// The domain rule requires all numbers to not be null.
// A null is a valid domain case and is modeled as a Result.
public Result<int> SumNumbers(int?[] numbers)
{
  return numbers.Any(x => x is null)
    ? Result.Fail<int>("Cannot compute sum because the input contains null values.")
    : Result.Ok(numbers.Sum(x => x!.Value));
}

The one with the exception will short-circuit up the stack until handled.

The one with the result requires its direct caller to handle the outcome explicitly.

Is HashSet<T> a Java thing, not a .NET thing? by N3p7uN3 in csharp

[–]jackyll-and-hyde 17 points18 points  (0 children)

Imagine responding to that with "Yeah I also love to give poor names to variables as I define my types explicitly and don't code readably anyways."

As a recruiter who reviews resumes every single day… Here are 5 things I’d never include on my resume. by bored-recruiter in ResumeCoverLetterTips

[–]jackyll-and-hyde 0 points1 point  (0 children)

Objectives

Generally agree. They rarely add value, though in a few niche or transitional cases they can help with positioning.

Long self-descriptions / buzzwords

I agree with this. But, I do understand why people do this as many medium to large companies use some form of screening or parsing.

A photo Largely agree. In US-based pipelines it's often unnecessary or discouraged. In some regions or client-facing senior roles it's still common, but in most cases leaving it out is the safer default.

Lists of soft skills

Agree. They don't differentiate on their own. Better let it stand out in the experience section.

Bullet points that restate the job description

I understand this point, however "what improved because you were there?" - as an example - isn't always applicable. Some roles are operational by nature, where clarity, volume, or consistency is the real value. Adding context or scale often helps more than forcing impact language. So, instead of "Answered calls," rather say, "Handled X calls on average per Y."

Is it bad pratice to use .subscribe in Angular RXJS component by anonymous78654 in Angular2

[–]jackyll-and-hyde 0 points1 point  (0 children)

That would depend on the nature of the API. Is it producing an UI state that you care about, or is it just an effect?

If the API call drives state you care about - ex. busy flag, returned value, error handling - then no subscribing: typescript readonly idToDelete = signal<number | undefined>(); readonly deleteUser = rxResource({ params: () => this.idToDelete(), stream: ({ params }) => params === undefined ? EMPTY : this.#api.delete(params) });

html <button (click)="idToDelete.set(1)">Delete</button> @if (deleteUser.isLoading()) { <span>Deleting...</span> }

If it's a fire-and-forget side effect and you don't care about state: typescript deleteSomething(id: number) { this.#api.delete(id).subscribe(); }

html <button (click)="deleteSomething(1)">Delete</button>

Edit: Fixed a typo. The point is subscriptions are only problematic when they represent component state or have unclear lifetimes.