Range
, in which virtual methods were used to walk through the elements in a range. Unfortunately, this class was not ideal, since it did not take into account certain borderline cases. However, this article is not so much about designing an ideal class for working with bands, but about what nuances and considerations should be taken into account. My MiscUtil class library contains a class that takes into account most of the things discussed in this article, but, of course, this class is far from ideal. In general, in January 2008, I wrote a short article about ranges in my blog, but since then a lot of water has flowed, I rethought a lot of things and decided to expand the topic in more detail in the form of this article.T
, which would require that type T
implement the IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
interface IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null «» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . null
«» , - null
; « », null
— , . , , , default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , . Contains
, - , .
() (). , , . ( readonly
) - , .
WithExclusiveLowerBound
, WithInclusiveLowerBound
, WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , - IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: , IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255) Byte
. :
: , , — . , «». :
* Func<Tuple<bool, T>>
, .
* ( out
) ( )
* null
« », , T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? , Compare
(negate) … , originalComparer.Compare
int.MinValue
. , , int.MinValue
. — , , , .
. , int.MinValue
. IComparer , , , int Compare(T x, T y) , : x
y
0; x
y
, 0; x
, y
, 0. .NET Framework, , x
y
-1 +1, , int.MinValue
( x
y
) int.MaxValue
( x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
, int.MaxValue
, . , ( checked
), System.OverflowException
, production- .
, , Range
Reverse
:
public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . , [0, 5]
(.. 0 5 ), , 2 . { 0, 2, 4 }
. [0, 5]
[5, 0]
, ( , 2), { 5, 3, 1 }
. , , LINQ, { 4, 2, 0 }
— { 5, 3, 1 }
.
, « », , . , ; , , . , , , , int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , , RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,
default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .
public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .
WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :
var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -
IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,
IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :
public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :
T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :
public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,
Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
IComparable. , , C# — IComparable. , , . , , (reversing) , . , .
«» , -
— , «-», , (). : IComparer, Comparison? , IComparer, , , . , Comparer.Default . , , Comparison, , - ( MiscUtil).
, , : «» , , , , «» ? , , , «», API .
, , , , . :
() (inclusive) (exclusive), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . nullnull
; « »,null
— , . , , ,default(IComparer), , , null
. .
, : (immutable). , , , , , «» (, ) .
. — .public sealed class Range<T> { public T LowerBound { get; private set; } public T UpperBound { get; private set; } public bool InclusiveLowerBound { get; private set; } public bool InclusiveUpperBound { get; private set; } public IComparer<T> Comparer { get; private set; } public Range(T lowerBound, T upperBound, bool inclusiveLowerBound = true, bool inclusiveUpperBound = false, IComparer<T> comparer = null) { LowerBound = lowerBound; UpperBound = upperBound; InclusiveLowerBound = inclusiveLowerBound; InclusiveUpperBound = inclusiveUpperBound; Comparer = comparer ?? Comparer<T>.Default; if (Comparer.Compare(LowerBound, UpperBound) > 0) { throw new ArgumentException("Invalid bounds"); } } public bool Contains(T item) { int lowerCompare = Comparer.Compare(LowerBound, item); if (lowerCompare > (InclusiveLowerBound ? 0 : -1)) { return false; } int upperCompare = Comparer.Compare(item, UpperBound); if (upperCompare > (InclusiveUpperBound ? 0 : -1)) { return false; } return true; } }
, , , … . , «» (.. ) / , .Contains
, - , .
() (). , , . (readonly
) - , .WithExclusiveLowerBound
,WithInclusiveLowerBound
,WithLowerBound
.., . -, , . - :var range = Range.Of(5, 10);
, — ́ , , . , , .
. , ( , stepping function), . : , , .
?
, — . , — . , (0, 50), , — 5. 1 ( ) 5 ( 0 )? , , , () . , -IComparer, . «» (41, 37), 23, 12 44, 38. .
, , . , — , , :
var range = new Range<int>(0, 50, false, false); var simpleIterable = range.StepBy(x => x + 5); var equivalentIterable = range.WithInclusiveLowerBound() .StepBy(x => x + 5) .Skip(1);
: ,IEnumerable. IEnumerator, IEnumerable: foreach
, LINQ ..
, …
?
-, . , «» , , . , , (0, 255)Byte
. :
: , , — . , «». :
*Func<Tuple<bool, T>>
, .
* (out
) ( )
*null
« », ,T
.
, «» - , () ( «»).
, , , , , « n ». , , , .
, , , . MiscUtil, , — . , . MiscUtil ( Marc Gravell ), , (+), , .
, :public IEnumerable<T> StepBy(Func<T, T> step) { T current = LowerBound; // , if (!InclusiveLowerBound) { current = step(current); } while (Contains(current)) { yield return current; T next = step(current); // Handle a stepping function which wraps // round from a value near the end to one // near the start; or a stepping function // which does nothing. if (Comparer.Compare(next, current) <= 0) { yield break; } current = next; } }
: «» , , , . , : , , , , , , , .
( if) — :T current = InclusiveLowerBound ? LowerBound : step(LowerBound);
— , — .
: . , — ?
(reversing) , . , «» / «» , . , (reversing comparer) — , , . , «» :public sealed class ReverseComparer<T> : IComparer<T> { private readonly IComparer<T> originalComparer; public ReverseComparer(IComparer<T> originalComparer) { this.originalComparer = originalComparer; } public int Compare(T x, T y) { return originalComparer.Compare(y, x); } }
« », ? ,Compare
(negate) … ,originalComparer.Compare
int.MinValue
. , ,int.MinValue
. — , , , .
. ,int.MinValue
.
IComparer , , , int Compare(T x, T y) , : x
y
0;x
y
, 0;x
,y
, 0. .NET Framework, ,x
y
-1 +1, ,int.MinValue
(x
y
)int.MaxValue
(x
y
). , . 0 ,
|int.MinValue| == int.MaxValue + 1. ,Int32 i = Int32.MinValue; Int32 j = -i;
j
int.MinValue
,int.MaxValue
, . , (checked
),System.OverflowException
, production- .
, ,Range
Reverse
:public Range<T> Reverse() { return new Range<T>( lowerBound: UpperBound, upperBound: LowerBound, inclusiveLowerBound: InclusiveUpperBound, inclusiveUpperBound: InclusiveLowerBound, comparer:new ReverseComparer<T>(Comparer)); }
, , , «» ( , ), . , C# 4, , , , .
, : , , , . ,[0, 5]
(.. 0 5 ), , 2 .{ 0, 2, 4 }
.[0, 5]
[5, 0]
, ( , 2),{ 5, 3, 1 }
. , , LINQ,{ 4, 2, 0 }
—{ 5, 3, 1 }
.
, « », , . , ; , , . , , , ,int.MinValue
. , , -, .
, , , .NET.
Dmitri Nstruk. Ranges in C# Qwertie. D-style ranges in C# (.NET) Sean Hederman. Building a Generic Range class Scott McMaster. RangeSet: A Low-Memory Set Data Structure for Integers Jay Bazuzi. Comparing ranges Sergio Pereira. Language Envy - C# needs Ranges Andy Clymer. Ruby Ranges in .NET
, , MiscUtil. , , . -, , , . Range MiscUtil , ,RangeIterator. , MiscUtil, , " ".
, Time Period Library Jani Giannoudis. 2011 CodeProject, ( — 1 2013), - ( - ), Silverlight Windows Phone. overkill hDrummer .
Source: https://habr.com/ru/post/197024/
All Articles