I recently found out that a class library I have been building, xofz.Core, could mostly be salvaged and back-ported to .NET Framework 2.0. This enables it to be used to build applications for Windows 98! How cool is that?
Here is a link to the repository: https://github.com/spearson/xofz.Core98
And the class I would like looked over most now is the Tuple implementation. It started out as a clone of the Tuple class from .NET 4 and on, but then just got AtomicGet() and AtomicSet() methods. What do you think of this class, and in particular those methods? I'm not precisely sure, but I imagine they could have a real use down the line.
Here are the tuple classes:
namespace xofz
{
using System.Threading;
public class Tuple<T, U>
{
public Tuple(T item1, U item2)
{
this.Item1 = item1;
this.Item2 = item2;
}
public virtual T Item1 { get; private set; }
public virtual U Item2 { get; private set; }
public virtual void AtomicGet(out T item1, out U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
private int settingOrGettingIf1;
}
public class Tuple<T, U, V>
{
public Tuple(
T item1,
U item2,
V item3)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
}
public virtual T Item1 { get; private set; }
public virtual U Item2 { get; private set; }
public virtual V Item3 { get; private set; }
public virtual void AtomicGet(out T item1, out U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out U item2, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item2 = this.Item2;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(U item2, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item2 = item2;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out U item2, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
private int settingOrGettingIf1;
}
public class Tuple<T, U, V, W>
{
public Tuple(
T item1,
U item2,
V item3,
W item4)
{
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
}
public virtual T Item1 { get; private set; }
public virtual U Item2 { get; private set; }
public virtual V Item3 { get; private set; }
public virtual W Item4 { get; private set; }
public virtual void AtomicGet(out T item1, out U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out U item2, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item2 = this.Item2;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(U item2, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item2 = item2;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out U item2, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item2 = this.Item2;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(U item2, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item2 = item2;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out V item3, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item3 = this.Item3;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(V item3, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item3 = item3;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out U item2, out V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2, V item3)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out U item2, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, U item2, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out T item1, out V item3, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item3 = this.Item3;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(T item1, V item3, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item3 = item3;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(out U item2, out V item3, out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(U item2, V item3, W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicGet(
out T item1,
out U item2,
out V item3,
out W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
item1 = this.Item1;
item2 = this.Item2;
item3 = this.Item3;
item4 = this.Item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
public virtual void AtomicSet(
T item1,
U item2,
V item3,
W item4)
{
while (Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 1, 0) == 1)
{
continue;
}
this.Item1 = item1;
this.Item2 = item2;
this.Item3 = item3;
this.Item4 = item4;
Interlocked.CompareExchange(
ref this.settingOrGettingIf1, 0, 1);
}
private int settingOrGettingIf1;
}
public static class Tuple
{
public static Tuple<T, U> Create<T, U>(
T item1,
U item2)
{
return new Tuple<T, U>(
item1,
item2);
}
public static Tuple<T, U, V> Create<T, U, V>(
T item1,
U item2,
V item3)
{
return new Tuple<T, U, V>(
item1,
item2,
item3);
}
public static Tuple<T, U, V, W> Create<T, U, V, W>(
T item1,
U item2,
V item3,
W item4)
{
return new Tuple<T, U, V, W>(
item1,
item2,
item3,
item4);
}
}
}
On a side note, I hope this class benefits someone else and maybe other items in the class library, as well.
virtual
? Can't think of any good reason why I would subclass a tuple. \$\endgroup\$Interlocked
parts and the helper variable? \$\endgroup\$Tuple
instances in your tests as well. The Interlocked.CompareExchange parts helps keep reading and writing atomic - if you read, you read the last values that were actually put in the Tuple, not some mix of values based on what was written to and by which thread. It's the only argument for mutability of tuples I could make. \$\endgroup\$