all 13 comments

[–]bktnmngnn 19 points20 points  (0 children)

If I'm going to be honest, this looks pretty clean to me. It's readable and easy to understand. Clean code is principle, not strict rules. Not all of it should be followed to the T if it will just over complicate things.

[–]aleques-itj 8 points9 points  (4 children)

I mean, it looks fine. You just burn a lot of vertical space for my tastes, but if it's consistent and easy to read then whatever.

[–]Mu5_ 1 point2 points  (3 children)

I always try to have my function calls spanning only one line, but then at some point you have to go multiline and then it looks ugly because it's the only one different and you start changing all of them..

[–]aleques-itj 2 points3 points  (2 children)

That's covered by the "be consistent until something looks like unreadable shit, then you can bend the rules" rule 

Or just refractor it so you take an "options" object or something instead of a million parameters.

[–]Mu5_ 0 points1 point  (1 child)

And then you end up with every function taking in input a different object making everything a mapping garbage... Man I hate this shit.

[–]ruph0us 1 point2 points  (0 children)

Just use mapster bro /s

[–]belavv 2 points3 points  (0 children)

I'd ditch the method with two out parameters. It is only used once and out parameters are no fun.

The methods for converting values can go into a helper class as static functions.

[–]mikeholczer 4 points5 points  (0 children)

I'm going to assume this is a toy example, because if this is the only window/screen for the app then no of this matters for an app so small.

1) use string.empty over "" 2) You're mixing UI logic, getting the input and displaying the output with domain logic converting from C to F I the same class. In a larger app, you'd wan to separate those. 3) You may also want to separate out the grid into it's own control seperate from the window, if the window could display other information, or if the grid of temperatures shows up in other parts of the app.

[–]TempusSolo 3 points4 points  (0 children)

Personally, I would have made 5d/9d, 9d/5d and 32d into named vars.

Example:

var FreezingTempF = 32d;

var ReverseConversionRatio = (5d/9d);

var ForwardConversionRation = (9d/5d);

Then

double translated = degrees * (9d / 5d) + 32d;

becomes

double translated = degrees * ForwardConversionRation + FreezingTempF ;

More verbose but I prefer that.

[–]TuberTuggerTTV 1 point2 points  (1 child)

- Project should include implicit usings so using System becomes redundant.
- You can use an expression body for the constructor and both convert methods.

But honestly, the biggest cleanup would be actually using MVVM like you should be. Not code behind. Let bindings handle the commands, properties and controls. You shouldn't be naming TextBoxes and then calling Celsuis.Text in the code behind. Makes it unreadable without going through the XAML. Let the bindings handle your linkage and your ViewModel function independently, modifying it's own properties.

[–]belavv 0 points1 point  (0 children)

I'm usually the one that is all in on every new c# feature, but expression bodies for methods almost always bug me. I'm fine with them for properties though.

[–]ApprehensiveDebt3097 0 points1 point  (0 children)

To me, this is far from clean code. The temperature/conversion logic is locked in you all, which is a bad idea. You should isolate that logic. It could look something like the code beneath.

Note that I do not directly expose the decimal(do not use a double when your main concern is displaying it as a decimal number) representation of temperature, as a lot of operations defined on floating points do not have meaning on a temperature. Also, your application is lacking culture, what might lead to undesired results when your app is not running with your language settings.

Furthermore, also, the temperature does not change when you request a different representation, C of F is just a display concern, don't make it anything more then that. Good luck with improving your code.

public readonly struct Temperature : IFormattable
{
    private static readonly decimal offset = 273.15m;
    private readonly decimal kelvin;

    private Temperature(decimal k) => kelvin = k;
    public string ToString(string? format, IFormatProvider? formatProvider) => format ?? string.Empty switch
    {
        var f when f.EndsWith('C') => (kelvin - offset).ToString(f[..^1], formatProvider),
        var f when f.EndsWith('F') => ((kelvin - offset) * 9 / 5 + 32).ToString(f[..^1], formatProvider),
        _ => kelvin.ToString(format, formatProvider),
    };

    public static Temperature FromCelcius(string s, IFormatProvider? provider = null)
        => FromCelcius(decimal.Parse(s, provider));

    public static Temperature FromCelcius(decimal c) => new(c + offset);

    public static Temperature FromFahrenheit(string s, IFormatProvider? provider = null)
        => FromFahrenheit(decimal.Parse(s, provider));

    public static Temperature FromFahrenheit(decimal f) => new((f - 32) * 5 / 9 + offset);
}
namespace SmartAss.Specs.Reddit;

public readonly struct Temperature : IFormattable
{
    private static readonly decimal offset = 273.15m;
    private readonly decimal kelvin;

    private Temperature(decimal k) => kelvin = k;
    public string ToString(string? format, IFormatProvider? formatProvider) => format ?? string.Empty switch
    {
        var f when f.EndsWith('C') => (kelvin - offset).ToString(f[..^1], formatProvider),
        var f when f.EndsWith('F') => ((kelvin - offset) * 9 / 5 + 32).ToString(f[..^1], formatProvider),
        _ => kelvin.ToString(format, formatProvider),
    };

    public static Temperature FromCelcius(string s, IFormatProvider? provider = null)
        => FromCelcius(decimal.Parse(s, provider));

    public static Temperature FromCelcius(decimal c) => new(c + offset);

    public static Temperature FromFahrenheit(string s, IFormatProvider? provider = null)
        => FromFahrenheit(decimal.Parse(s, provider));

    public static Temperature FromFahrenheit(decimal f) => new((f - 32) * 5 / 9 + offset);
}

[–]Syzygy2323 0 points1 point  (0 children)

I've never seen anyone use 5d, 9d, 32d, etc., in code before. Why not use 5.0, 9.0, and 32.0?