GeWuYou dfbd6a69c5 feat(ArrayExtensions): 添加二维数组扩展方法
- 添加 GetOrDefault 方法用于获取越界时返回默认值的元素
- 添加 GetOr 方法用于获取越界时返回指定回退值的元素
- 添加 TryGet 方法用于尝试获取指定位置的元素
- 添加 GetNeighbors4 方法用于获取四个方向的邻居坐标
- 添加 GetNeighbors8 方法用于获取八个方向的邻居坐标
- 添加 Enumerate 方法用于枚举数组中所有元素及坐标
- 添加 Width 和 Height 方法分别获取数组宽高维度
- 在文件头注释中修复版权年份格式问题
2026-03-29 22:54:15 +08:00

168 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace GFramework.Core.Extensions;
/// <summary>
/// 数组扩展方法类,提供二维数组的边界检查等实用功能。
/// </summary>
public static class ArrayExtensions
{
/// <summary>
/// 检查二维数组的给定坐标是否在有效边界内。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要检查的二维数组。</param>
/// <param name="x">要检查的 X 坐标(第一维索引)。</param>
/// <param name="y">要检查的 Y 坐标(第二维索引)。</param>
/// <returns>如果坐标在数组边界内则返回 true否则返回 false。</returns>
public static bool IsInBounds<T>(this T[,] array, int x, int y)
{
return x >= 0 && y >= 0 &&
x < array.GetLength(0) &&
y < array.GetLength(1);
}
/// <summary>
/// 获取二维数组指定位置的元素,如果越界则返回默认值。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要访问的二维数组。</param>
/// <param name="x">X 坐标(第一维索引)。</param>
/// <param name="y">Y 坐标(第二维索引)。</param>
/// <returns>如果在边界内返回该位置的元素;否则返回类型的默认值。</returns>
public static T? GetOrDefault<T>(this T[,] array, int x, int y)
{
return array.IsInBounds(x, y) ? array[x, y] : default;
}
/// <summary>
/// 获取二维数组指定位置的元素,如果越界则返回指定的回退值。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要访问的二维数组。</param>
/// <param name="x">X 坐标(第一维索引)。</param>
/// <param name="y">Y 坐标(第二维索引)。</param>
/// <param name="fallback">当坐标越界时返回的回退值。</param>
/// <returns>如果在边界内返回该位置的元素;否则返回指定的回退值。</returns>
public static T GetOr<T>(this T[,] array, int x, int y, T fallback)
{
return array.IsInBounds(x, y) ? array[x, y] : fallback;
}
/// <summary>
/// 尝试获取二维数组指定位置的元素。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要访问的二维数组。</param>
/// <param name="x">X 坐标(第一维索引)。</param>
/// <param name="y">Y 坐标(第二维索引)。</param>
/// <param name="value">输出参数,用于存储获取到的元素值。</param>
/// <returns>如果成功获取元素则返回 true否则返回 false。</returns>
public static bool TryGet<T>(this T[,] array, int x, int y, out T value)
{
if (array.IsInBounds(x, y))
{
value = array[x, y];
return true;
}
value = default!;
return false;
}
/// <summary>
/// 获取二维数组中某个位置的四个方向邻居坐标(上、下、左、右)。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">源二维数组。</param>
/// <param name="x">中心位置的 X 坐标。</param>
/// <param name="y">中心位置的 Y 坐标。</param>
/// <returns>按顺序返回所有在边界内的邻居坐标。</returns>
public static IEnumerable<(int x, int y)> GetNeighbors4<T>(this T[,] array, int x, int y)
{
var dirs = new (int dx, int dy)[]
{
(0, -1), (0, 1),
(-1, 0), (1, 0)
};
foreach (var (dx, dy) in dirs)
{
var nx = x + dx;
var ny = y + dy;
if (array.IsInBounds(nx, ny))
yield return (nx, ny);
}
}
/// <summary>
/// 获取二维数组中某个位置的八个方向邻居坐标(包括对角线)。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">源二维数组。</param>
/// <param name="x">中心位置的 X 坐标。</param>
/// <param name="y">中心位置的 Y 坐标。</param>
/// <returns>按顺序返回所有在边界内的邻居坐标(不包括中心位置)。</returns>
public static IEnumerable<(int x, int y)> GetNeighbors8<T>(this T[,] array, int x, int y)
{
for (var dx = -1; dx <= 1; dx++)
{
for (var dy = -1; dy <= 1; dy++)
{
if (dx == 0 && dy == 0) continue;
var nx = x + dx;
var ny = y + dy;
if (array.IsInBounds(nx, ny))
yield return (nx, ny);
}
}
}
/// <summary>
/// 枚举二维数组中的所有元素及其坐标。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要枚举的二维数组。</param>
/// <returns>依次返回每个元素的坐标和值的元组。</returns>
public static IEnumerable<(int x, int y, T value)> Enumerate<T>(this T[,] array)
{
for (var x = 0; x < array.GetLength(0); x++)
{
for (var y = 0; y < array.GetLength(1); y++)
{
yield return (x, y, array[x, y]);
}
}
}
/// <summary>
/// 获取二维数组的宽度(第一维长度)。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要获取宽度的二维数组。</param>
/// <returns>数组的第一维长度。</returns>
public static int Width<T>(this T[,] array) => array.GetLength(0);
/// <summary>
/// 获取二维数组的高度(第二维长度)。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="array">要获取高度的二维数组。</param>
/// <returns>数组的第二维长度。</returns>
public static int Height<T>(this T[,] array) => array.GetLength(1);
}