अनुवादक से। .NET में श्रेणियों (अंतराल) का विषय सही रूप से हमेशा के लिए हरे और युवा को संदर्भित करता है। मंचों पर पूछे गए सैकड़ों प्रश्न, लिखे गए दर्जनों लेख ... ऐसा लगता है कि यह केवल तभी समाप्त होगा जब Microsoft आखिरकार फ्रेमवर्क क्लास लाइब्रेरी में श्रेणियों के साथ काम करने के लिए अपने तंत्र का परिचय देता है। और इसके लिए एक तार्किक व्याख्या है - शायद, हर प्रोग्रामर जल्द या बाद में मूल्यों की एक निश्चित सीमा का उपयोग करने की आवश्यकता का सामना करता है, चाहे वह संख्याएं, तिथियां या किसी भी अन्य मान हों। मुझे भी इस तरह की आवश्यकता थी, हालांकि, यह याद रखना कि मेरी बाइक सबसे अच्छा समाधान नहीं थी, मैं इंटरनेट के माध्यम से चला गया और जॉन स्कीट का उत्कृष्ट लेख मिला, जिसका अनुवाद, वास्तव में, मैं आपके ध्यान में प्रस्तुत करता हूं।मेरी पुस्तक के पहले संस्करण, "
गहराई में C # "
, एक अमूर्त जेनेरिक
Range
क्लास का हवाला दिया
, जो एक सीमा में तत्वों को पार करने के लिए आभासी तरीकों का इस्तेमाल करता था। दुर्भाग्य से, यह वर्ग अपूर्ण था, क्योंकि यह कुछ सीमावर्ती मामलों को ध्यान में नहीं रखता था। हालांकि, यह लेख श्रेणियों के साथ काम करने के लिए एक आदर्श वर्ग को डिजाइन करने के बारे में इतना नहीं बताता है, लेकिन इसके बारे में बारीकियों और विचारों को ध्यान में रखा जाना चाहिए। मेरे
MiscUtil वर्ग के पुस्तकालय में एक वर्ग होता है जो इस लेख में चर्चा की गई अधिकांश चीजों को ध्यान में
रखता है , लेकिन निश्चित रूप से, यह वर्ग आदर्श से बहुत दूर है। सामान्य तौर पर, जनवरी 2008 में, मैंने अपने ब्लॉग पर श्रेणियों के बारे में एक
छोटा लेख लिखा था, लेकिन तब से बहुत सारा पानी बह चुका है, मैंने बहुत सी चीजों पर पुनर्विचार किया और इस लेख के रूप में अधिक विस्तार से विषय पर विस्तार करने का निर्णय लिया।
समस्या का बयान
आइए हम पहले यह निर्धारित करें कि हम क्या चाहते हैं और हम क्या कर सकते हैं, और हम कार्य को यथासंभव विशिष्ट रूप से तैयार करेंगे।
- किसी भी उपयुक्त प्रकार के लिए मान श्रेणी संग्रहण इंजन बनाएँ
- कस्टम एन्यूमरेशन फ़ंक्शन का उपयोग करके इन मानों के सेट पर फेरबदल करें
ऐसा लगता है कि हम हर तरह का वर्णन करते हैं, लेकिन याद रखें कि शैतान विवरण में है। हमें निम्नलिखित बातों पर भी विचार करना चाहिए, अर्थात्:
- दो श्रेणियों की समानता पर विचार करें
- चौराहे, संघ, अंतर आदि पर विचार करें। दो रेंज
- उन सीमाओं को ध्यान में रखें जिनके मूल्य असतत मूल्य हैं (जैसे कि "0 से 100 की सीमा में सभी पूर्णांक)"
- सीमा पर "ले जाने" वाले खोज फ़ंक्शंस से निपटने के लिए (यानी, यह निर्धारित करें कि उन्हें किस दिशा में बढ़ना चाहिए, आदि)
अब जब हमने समस्या को सामान्य शब्दों में बना लिया है, तो हम छोटे विवरणों पर आगे बढ़ सकते हैं।
विवरण
सबसे पहले, आइए उन प्रकारों के बारे में सोचें जो आम तौर पर श्रेणियों में उपयोग के लिए मान्य हैं। हम चाहते हैं कि श्रेणी वर्ग जेनेरिक हो, और हम यह जानना चाहते हैं कि एक दूसरे के साथ दो मूल्यों की तुलना की जा सकती है, ताकि यह पता चल सके कि कौन सा बड़ा है और कौन सा छोटा है। हम
T
को टाइप करने के लिए इस तरह की बाधा को लागू करके इसे प्राप्त कर सकते हैं, जिसे टाइप करने के लिए उस प्रकार की आवश्यकता होती है जैसे कि
T
उपयोग करने योग्य इंटरफ़ेस
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), , . , , ? , , .. ? , ()? , ?
, , .. , , . , (), — (). , , «» «» . , , . 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 .