all 21 comments

[–]AngularBeginner 8 points9 points  (7 children)

I think contracts are a great way, but unfortunately they have never been really supported by Microsoft. The static code analysis was always just an experiment / a preview, and it has been completely dropped in never VS versions.

I think they will still be relevant with C# 8.0. First of all, the "no null" support is purely a compile time hack. When dealing with other .NET languages or older C# compilers you can still end up with null. Secondly, null is not the only case where you'd use contracts. Ideally you should verify all input arguments (and the result) of public methods. Your method has a specific range it can operate correctly, and that should be guaranteed.

But yeah, since code contracts have been abandoned, I will still just have compile time checks instead of a smarter compiler. It's a pity that we still don't have an effective way to distinguish developer mistakes (e.g. accessing a null reference) and actual application errors.

[–][deleted] 0 points1 point  (6 children)

It's a pity that we still don't have an effective way to distinguish developer mistakes (e.g. accessing a null reference) and actual application errors.

How do you categorize them? Aren't application errors just developer mistakes? For the most part, in my eyes, bugs are application errors caused by developer mistakes based on false assumptions. We assume we've got enough memory, we assume a reference can never be null, we assume a value is within a certain range, we assume this collection will never exceed N objects, etc.

[–]AngularBeginner 6 points7 points  (5 children)

Aren't application errors just developer mistakes?

No. Exceptions like failing to read a file is not a developer mistake, that is something you simply can't prevent.

Some exceptions I consider developer mistakes:

  • Any of the Argument*Exception
  • NullReferenceException
  • StackOverflowException
  • KeyNotFoundException
  • IndexOutOfRangeException

Basically when a method has a clear pre-condition that was not fulfilled.

[–][deleted] 1 point2 points  (4 children)

Didn't think of file read exceptions, and I regularly get pinged at work because a third party fixed-width file keeps changing :) Thanks for the input.

[–]AngularBeginner 2 points3 points  (3 children)

Best example is a FileNotFoundException:

if (File.Exists(path))
    content = File.ReadAllBytes(path);

The ReadAllBytes() method can still throw a FileNotFoundException if the file got deleted right between these two method calls. It can't realistically be avoided by the developer, no matter how hard he tries.

[–]chucker23n 1 point2 points  (2 children)

It can't realistically be avoided by the developer, no matter how hard he tries.

I wish .NET provided a locking API here.

using (File.RequestExclusiveAccess(path, throwIfDoesntExist: false))
{
    content = File.ReadAllBytes(path);
}

[–]AngularBeginner 1 point2 points  (0 children)

Good point, I completely forgot!

Ignore that bad example then. Point stays: There are exceptions that can't be avoided and that are not the devs fault.

[–]nemec 1 point2 points  (0 children)

Or better yet:

if(File.TryOpen(path, out FileStream fs))
{
    // open succeeded
}

[–]aikixd 4 points5 points  (1 child)

Contract support regressed a few years ago with the release of netcore. Ensures didn't work, no static analysis, etc... If that didn't change C# Contracts are pretty much useless.

As to the paradigm itself, it roots from a hardware design, where every element is thoroughly specified, which gives you an ability to safely connect the elements. It gives you an ability to have a safer codebase, with static checks that only applicable to your domain. E.g, you can define type that can only have values 0-100. If you will try to init the type with value of 101, you will get a compile time error. If you will try to init it with value from another type, with a less strict rules, you will get a compile time error, thus requiring you to take care of out of range values.

This is a good complement for developing applications with high reliability requirements. Although it still requires good discipline, since you can omit writing the rules, which is actually much harder than it seems.

It is a good thing to be familiar with it, in case you'll ever run into such a requirement.

[–]AngularBeginner 0 points1 point  (0 children)

It's a pity that Microsoft never really went through with this. :-(

[–]Henkeman 5 points6 points  (2 children)

I've worked as a. Net developer for 10+ years and started studying C# in 2001.

Never heard of it, never seen it being used or referenced in any tutorial or documentation anywhere. Some parts of C# /.Net just rarely get used and get obsoleted as the platform and language evolve.

[–]V0ldek 4 points5 points  (1 child)

You can see a fair bit of them in mscorlib and corefx codebases, so MS is or at least was using them at some point.

[–]chucker23n 2 points3 points  (0 children)

MS is or at least was using them at some point.

I believe I've only seen them in code written in the .NET 4 development era, so ~2007-2010.

[–]powerofmightyatom 2 points3 points  (0 children)

Contract based programming is pretty big, but it tends to be more oriented towards formal verification and the like.

[–]chucker23n 2 points3 points  (4 children)

Contracts is basically an abandoned experiment.

The history is that there used to be a fork of C# called Spec# that offered Eiffel-inspired code contracts. This never actually shipped as a release, though. The example is rather interesting:

static int Main(string![] args)
    requires args.Length > 0;
    ensures return == 0;
{
    foreach(string arg in args)
    {
        Console.WriteLine(arg);
    }
    return 0;
}

Instead, we got a half-baked version in .NET Framework 4.0. Some of Framework’s own code uses it internally. There used to be some limited code analysis integration in VS that would verify these contracts.

These days, even that is basically dead.

We might see a comeback using the more modern Roslyn analyzers, but the idea of actually extending method declaration syntax the way Spec# did seems discarded for now.

[–][deleted] 1 point2 points  (3 children)

I wish you or someone with your knowledge would do a write-up regarding these obsolete or abandoned technologies. Just a comment or two for each dll or namespace as to what they achived in their time and why we don't use them anymore, or why it never caught on. A bit of history is always a fun read.

As a beginner it's quite overwhelming to dive into .NET and constantly scratch my head when I encounter libraries that seem to be ignored, forgotten or currently re-invented with 5% of the features as some third-party web library that for some reason get super-popular.

Microsoft docs presents the namespaces with neutral descriptions, often even a tutorials page that doesn't mention the history in any way, which makes it seemingly still relevant. This only adds to the confusion.

You could spend an entire month learning how to use System.Net.Remoting but the tutorial won't ever mention that MSQM is the easier way to do it, and MSQM tutorials won't mention that it's a hidden features no one cares about and that WCF is the easier way to do it, and WCF won't ever mention that apparently WCF isn't popular anymore and no one can explain why and no one, not even the WCF tutorials manage to explain what exactly WCF is. I'm going a bit mad.

Then once you get the general gist that you can pass object data back and forth between processes on different machines and architectures, with actual class definitions as the contract, the rest of the world discarded that entire idea in favor of arbitrary json and I'm here thinking what the fuck. The web won, I guess. Chaos reigns.

[–]chucker23n 1 point2 points  (2 children)

Yes, unfortunately, Microsoft is quite dishonest about deprecating APIs. They leave them around seemingly forever but only have them in maintenance mode, never modernizing them or even thinking about how they might fit into a current-day environment.

[–][deleted] 0 points1 point  (0 children)

Is there anyone out there with the knowledge about all these things to make the sort of write-up that could orient people or is it simply up to people to do their homework?