Is there a C# type for representing an integer Range?
I have a need to store an integer range. Is there an existing type for that in C# 4.0?
Of course, I could write my own class with int From
and int To
properties and build in proper logic to ensure that From <= To
. But if a type already exists, I'd of course rather use that.
I found it best to roll my own. Some people use Tuple
s or Point
s, but in the end you want your Range
to be extensive and provide some handy methods that relate to a Range
. It's also best if generic (what if you need a range of Double
s, or a range of some custom class?) For example:
/// <summary>The Range class.</summary>
/// <typeparam name="T">Generic parameter.</typeparam>
public class Range<T> where T : IComparable<T>
{
/// <summary>Minimum value of the range.</summary>
public T Minimum { get; set; }
/// <summary>Maximum value of the range.</summary>
public T Maximum { get; set; }
/// <summary>Presents the Range in readable format.</summary>
/// <returns>String representation of the Range</returns>
public override string ToString()
{
return string.Format("[{0} - {1}]", this.Minimum, this.Maximum);
}
/// <summary>Determines if the range is valid.</summary>
/// <returns>True if range is valid, else false</returns>
public bool IsValid()
{
return this.Minimum.CompareTo(this.Maximum) <= 0;
}
/// <summary>Determines if the provided value is inside the range.</summary>
/// <param name="value">The value to test</param>
/// <returns>True if the value is inside Range, else false</returns>
public bool ContainsValue(T value)
{
return (this.Minimum.CompareTo(value) <= 0) && (value.CompareTo(this.Maximum) <= 0);
}
/// <summary>Determines if this Range is inside the bounds of another range.</summary>
/// <param name="Range">The parent range to test on</param>
/// <returns>True if range is inclusive, else false</returns>
public bool IsInsideRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && range.ContainsValue(this.Minimum) && range.ContainsValue(this.Maximum);
}
/// <summary>Determines if another range is inside the bounds of this range.</summary>
/// <param name="Range">The child range to test</param>
/// <returns>True if range is inside, else false</returns>
public bool ContainsRange(Range<T> range)
{
return this.IsValid() && range.IsValid() && this.ContainsValue(range.Minimum) && this.ContainsValue(range.Maximum);
}
}
Ranges and Indices are released with C#8.0 and .NET Core.
You are now able to do
string[] names =
{
"Archimedes", "Pythagoras", "Euclid", "Socrates", "Plato"
};
foreach (var name in names[1..4])
{
yield return name;
}
Check out https://blogs.msdn.microsoft.com/dotnet/2018/12/05/take-c-8-0-for-a-spin/ for more detail.
Just a small class I wrote which could be helpful for someone:
public class Range
{
public static List<int> range(int a, int b)
{
List<int> result = new List<int>();
for(int i = a; i <= b; i++)
{
result.Add(i);
}
return result;
}
public static int[] Understand(string input)
{
return understand(input).ToArray();
}
public static List<int> understand(string input)
{
List<int> result = new List<int>();
string[] lines = input.Split(new char[] {';', ','});
foreach (string line in lines)
{
try
{
int temp = Int32.Parse(line);
result.Add(temp);
}
catch
{
string[] temp = line.Split(new char[] { '-' });
int a = Int32.Parse(temp[0]);
int b = Int32.Parse(temp[1]);
result.AddRange(range(a, b).AsEnumerable());
}
}
return result;
}
}
Then you just call:
Range.understand("1,5-9,14;16,17;20-24")
And the result looks like:
List<int>
[0]: 1
[1]: 5
[2]: 6
[3]: 7
[4]: 8
[5]: 9
[6]: 14
[7]: 16
[8]: 17
[9]: 20
[10]: 21
[11]: 22
[12]: 23
[13]: 24