C\#Index 와 Range 를 어떻게 사용 하여 집합 작업 을 간소화 합 니까?

8207 단어 c#IndexRange
Intro
어떤 언어 배열 의 색인 값 은 음 수 를 지원 하 며 뒤에서 앞으로 색인 하 는 것 을 나타 낸다.예 를 들 어 arr[-1]
C\#8 부터 C\#는 배열 의 역방향 Index 를 지원 합 니 다.Range 작업 과 역방향 Index 는 다른 언어 에서 의 마이너스 색인 값 과 유사 하지만 사실은 컴 파일 러 가 우 리 를 도와 전환 을 했 습 니 다.Range 는 배열 에 대해 특정한 부분 을 캡 처 하 는 작업 이 매우 간단 할 것 입 니 다.다음은 어떻게 사용 하 는 지 살 펴 보 겠 습 니 다.
Sample
^집합 마지막 부터 색인 요 소 를 사용 할 수 있 습 니 다.배열 의 마지막 부터 색인 요 소 를 시작 하면 마지막 요 소 는 0 이 아 닌 1 이 어야 합 니 다.예 를 들 어 arr[^1]
사용...특정한 배열 을 기반 으로 집합 중의 한 단락 을 캡 처 하여 새로운 배열 을 만 들 수 있 습 니 다.예 를 들 어 var new Array=array[1..^1]다음 예제 를 살 펴 보 세 요.

int[] someArray = new int[5] { 1, 2, 3, 4, 5 };
int lastElement = someArray[^1]; // lastElement = 5
lastElement.Dump();

someArray[3..5].Dump();

someArray[1..^1].Dump();

someArray[1..].Dump();

someArray[..^1].Dump();

someArray[..2].Dump();
출력 결 과 는 다음 과 같 습 니 다.

Index
그러면 이것 은 어떻게 실현 되 었 습 니까?색인 값 은 새로운 데이터 구조 인 System.Index 를 도 입 했 습 니 다.^연산 자 를 사용 할 때 실제 적 으로 Index 로 바 뀌 었 습 니 다.
Index:

public readonly struct Index : IEquatable<Index>
{
 public Index(int value, bool fromEnd = false);

 /// <summary>Create an Index pointing at first element.</summary>
 public static Index Start => new Index(0);

 /// <summary>Create an Index pointing at beyond last element.</summary>
 public static Index End => new Index(~0);
 //
 // Summary:
 //  Gets a value that indicates whether the index is from the start or the end.
 //
 // Returns:
 //  true if the Index is from the end; otherwise, false.
 public bool IsFromEnd { get; }
 //
 // Summary:
 //  Gets the index value.
 //
 // Returns:
 //  The index value.
 public int Value { get; }

 //
 // Summary:
 //  Creates an System.Index from the end of a collection at a specified index position.
 //
 // Parameters:
 // value:
 //  The index value from the end of a collection.
 //
 // Returns:
 //  The Index value.
 public static Index FromEnd(int value);
 //
 // Summary:
 //  Create an System.Index from the specified index at the start of a collection.
 //
 // Parameters:
 // value:
 //  The index position from the start of a collection.
 //
 // Returns:
 //  The Index value.
 public static Index FromStart(int value);
 //
 // Summary:
 //  Returns a value that indicates whether the current object is equal to another
 //  System.Index object.
 //
 // Parameters:
 // other:
 //  The object to compare with this instance.
 //
 // Returns:
 //  true if the current Index object is equal to other; false otherwise.
 public bool Equals(Index other);
 //
 // Summary:
 //  Calculates the offset from the start of the collection using the given collection length.
 //
 // Parameters:
 // length:
 //  The length of the collection that the Index will be used with. Must be a positive value.
 //
 // Returns:
 //  The offset.
 public int GetOffset(int length);

 //
 // Summary:
 //  Converts integer number to an Index.
 //
 // Parameters:
 // value:
 //  The integer to convert.
 //
 // Returns:
 //  An Index representing the integer.
 public static implicit operator Index(int value);
}
사용자 정의 집합 지원 Index 와 같은 배열 의 마지막 색인 기능 을 지원 하려 면 Index 의 색인 기 를 추가 하면 됩 니 다.정방 향 색인 도 지원 합 니 다.int 는 자동 으로 암시 적 으로 Index 로 변 환 됩 니 다.색인 기 를 추가 하 는 것 외 에 암시 적 으로 지원 하여 int Count{get 을 실현 할 수 있 습 니 다.}의 속성(속성 이름 Length 도 가능),int 형식의 색인 기 를 실현 하면 됩 니 다.
간단 한 예 시 를 쓰 세 요.

private class TestCollection
{
 public IList<int> Data { get; init; }

 public int Count => Data.Count;
 public int this[int index] => Data[index];

 //public int this[Index index] => Data[index.GetOffset(Data.Count)];
}
var array = new TestCollection()
{
 Data = new[] { 1, 2, 3 }
};
Console.WriteLine(array[^1]);
Console.WriteLine(array[1]);
Range
Range 는 Index 를 바탕 으로 이 루어 집 니 다.Range 는 두 개의 Index 로 시작 과 끝 을 지정 해 야 합 니 다.

public readonly struct Range : IEquatable<Range>
{
 /// <summary>Represent the inclusive start index of the Range.</summary>
 public Index Start { get; }

 /// <summary>Represent the exclusive end index of the Range.</summary>
 public Index End { get; }

 /// <summary>Construct a Range object using the start and end indexes.</summary>
 /// <param name="start">Represent the inclusive start index of the range.</param>
 /// <param name="end">Represent the exclusive end index of the range.</param>
 public Range(Index start, Index end)
 {
  Start = start;
  End = end;
 }

 /// <summary>Create a Range object starting from start index to the end of the collection.</summary>
 public static Range StartAt(Index start) => new Range(start, Index.End);

 /// <summary>Create a Range object starting from first element in the collection to the end Index.</summary>
 public static Range EndAt(Index end) => new Range(Index.Start, end);

 /// <summary>Create a Range object starting from first element to the end.</summary>
 public static Range All => new Range(Index.Start, Index.End);

 /// <summary>Calculate the start offset and length of range object using a collection length.</summary>
 /// <param name="length">The length of the collection that the range will be used with. length has to be a positive value.</param>
 /// <remarks>
 /// For performance reason, we don't validate the input length parameter against negative values.
 /// It is expected Range will be used with collections which always have non negative length/count.
 /// We validate the range is inside the length scope though.
 /// </remarks>
 public (int Offset, int Length) GetOffsetAndLength(int length);
}
어떻게 자신의 클래스 에서 Range 를 지지 합 니까?
한 가지 방식 은 자신 이 직접 실현 하 는 것 입 니 다.한 가지 유형 은 Range 의 색인 기 입 니 다.
다른 방식 은 암시 적 실현 입 니 다.사용자 정의 클래스 에 Count 속성 을 추가 한 다음 에 하나의 Slice 방법 을 실현 합 니 다.Slice 방법 은 두 개의 int 유형의 매개 변수 가 있 습 니 다.첫 번 째 매개 변 수 는 offset 을 표시 하고 두 번 째 매개 변 수 는 length 를 표시 합 니 다.
아래 의 이 예 시 를 보 세 요.아니면 아까 그 종류 입 니까?우 리 는 Range 를 지지 합 니 다.

private class TestCollection
{
 public IList<int> Data { get; init; }
 //public int[] this[Range range]
 //{
 // get
 // {
 //  var rangeInfo = range.GetOffsetAndLength(Data.Count);
 //  return Data.Skip(rangeInfo.Offset).Take(rangeInfo.Length).ToArray();
 // }
 //}

 public int Count => Data.Count;

 public int[] Slice(int start, int length)
 {
  var array = new int[length];
  for (var i = start; i < length && i < Data.Count; i++)
  {
   array[i] = Data[i];
  }
  return array;
 }
}
More
새로운 조작 부호(^and..)는 모두 문법 사탕 일 뿐,본질 적 으로 Index,Range 를 호출 하 는 것 이다.
Index 는 음수 색인 을 지원 하 는 것 이 아 닙 니 다.마지막 으로 앞 에 있 는 색인 은 컴 파일 러 가 우리 에 게 이전 에서 뒤의 색인 값 으로 전환 시 켜 주 었 을 뿐 입 니 다.이 를 통 해 우 리 는 마지막 요 소 를 집합 하 는 문법 을 많이 취하 면 원래 의 array[array.Length-1]=>array[^1]에서 크게 간소화 할 수 있 습 니 다.
Range 는 특정한 배열 의 하위 서열 을 만 들 때 매우 편리 합 니 다.new Array=array[1.3].주의해 야 할 것 은 Range 는'왼쪽 닫 기 오른쪽 열 림'입 니 다.왼쪽 경계 값 을 포함 하고 오른쪽 경계 값 을 포함 하지 않 습 니 다.
Index/Range 를 사용 해 본 적 이 없 으 니 어서 체험 해 보 세 요.이 걸 로 배열 의 조작 을 최적화 하 세 요~~
이상 은 C\#Index 와 Range 를 어떻게 사용 하여 집합 작업 을 간소화 하 는 지 에 대한 상세 한 내용 입 니 다.c\#Index 와 Range 를 사용 하여 집합 작업 을 간소화 하 는 데 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 시기 바 랍 니 다!

좋은 웹페이지 즐겨찾기