Olipro
Olipro
CC#
Created by Olipro on 11/14/2024 in #help
IDisposable ownership semantics
This is primarily a question regarding whether or not C# has introduced any sort of syntactic sugar or support for a "nicer" way of expressing transfer of ownership. For the purposes of this question, nullable types is fully enabled and static analysis that will issue CA2000 as an error is also turned on. Consider a method that returns a type that implements IDisposable and needs to either return it, or ensure it gets Dispose'd if an exception occurs - Currently I'd write something like this:
public SomeDisposable getDisposable() {
var result = new SomeDisposable();
try {
//do possibly exception-throwing stuff here
var ret = result;
result = null;
return ret;
} finally {
result?.Dispose();
}
}
public SomeDisposable getDisposable() {
var result = new SomeDisposable();
try {
//do possibly exception-throwing stuff here
var ret = result;
result = null;
return ret;
} finally {
result?.Dispose();
}
}
Is there anything better than this? This sort of pattern feels about as manual as malloc and free in C.
28 replies
CC#
Created by Olipro on 11/12/2024 in #help
Selecting and filtering from a list with full nullable safety & warnings as errors
I have the type Btn in my sample below which simulates the portion of WinForms that I'm interested in. I have a list of Btn objects and my goal is to mutate it into a subset of Btn objects that have their Tag matching the Wanted type without being opaque to the static analyser that detects potential null references (and avoiding the null-forgiving operator) I ran the code below over on https://sharplab.io and it does not complain that OfType could return any nullables. Nonetheless, the code fails because the middle element (which will be a tuple of nulls) still gets returned. Is this an issue with the REPL or is the static analyser really not seeing that the tuple types could end up being null? Perhaps there is a cleaner way to achieve what I want. Do note that I cannot alter the type held by Btn.Tag, it's an object in WinForms and I have no control over the code that decided to expose the types via that field.
#nullable enable

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Btn {
public object Tag { get; private set; }
public string Str { get; private set; }
public Btn(object tag, string str) {
Tag = tag;
Str = str;
}
}

class Wanted {}
class Unwanted {}

class main {
public static void Main(string[] args) {
List<Btn> lst = [new Btn(new Wanted(), "A"),
new Btn(new Unwanted(), "B"),
new Btn(new Wanted(), "C")];

foreach (var tup in lst.Select(btn => btn.Tag is Wanted w ? (btn, w) : (null, null)).OfType<(Btn, Wanted)>())
Console.WriteLine(tup.Item1.Str);
}
}
#nullable enable

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Btn {
public object Tag { get; private set; }
public string Str { get; private set; }
public Btn(object tag, string str) {
Tag = tag;
Str = str;
}
}

class Wanted {}
class Unwanted {}

class main {
public static void Main(string[] args) {
List<Btn> lst = [new Btn(new Wanted(), "A"),
new Btn(new Unwanted(), "B"),
new Btn(new Wanted(), "C")];

foreach (var tup in lst.Select(btn => btn.Tag is Wanted w ? (btn, w) : (null, null)).OfType<(Btn, Wanted)>())
Console.WriteLine(tup.Item1.Str);
}
}
54 replies