Sage.Data.Extensions
1.0.1.1
dotnet add package Sage.Data.Extensions --version 1.0.1.1
NuGet\Install-Package Sage.Data.Extensions -Version 1.0.1.1
<PackageReference Include="Sage.Data.Extensions" Version="1.0.1.1" />
<PackageVersion Include="Sage.Data.Extensions" Version="1.0.1.1" />
<PackageReference Include="Sage.Data.Extensions" />
paket add Sage.Data.Extensions --version 1.0.1.1
#r "nuget: Sage.Data.Extensions, 1.0.1.1"
#:package Sage.Data.Extensions@1.0.1.1
#addin nuget:?package=Sage.Data.Extensions&version=1.0.1.1
#tool nuget:?package=Sage.Data.Extensions&version=1.0.1.1
Sage.Data.Extensions
简介
Sage.Data.Extensions 提供了一系列常用的数据类型扩展方法,简化了日常开发中的常见操作。该库设计为线程安全,并完全兼容 AOT 编译。
特性
- 字符串扩展方法(判空、格式化、类型转换等)
- 日期时间扩展方法(格式化、时间段计算等)
- 字节数组扩展方法(编码转换、哈希计算等)
- 整型和长整型扩展方法(范围检查、格式化等)
- 字典扩展方法(条件添加、转换为查询字符串等)
- JsonNode扩展方法(空数组处理等)
- 文件路径处理方法(获取文件名、扩展名、目录名、路径组合等)
- 显示文本处理方法(条件格式化、标题转换、无效值处理等)
- 线程安全设计
- 完全兼容 AOT 编译
安装
dotnet add package Sage.Data.Extensions
使用示例
字符串扩展方法 (StringExtensions)
空值检查和默认值处理
// 判断字符串是否为空(null、空字符串或仅包含空白字符)
string text = "";
bool isEmpty = text.IsEmpty(); // 返回 true
string text2 = " ";
bool isEmpty2 = text2.IsEmpty(); // 返回 true
string text3 = "Hello";
bool isEmpty3 = text3.IsEmpty(); // 返回 false
// 判断字符串是否为null或空字符串(不考虑空白字符)
string text4 = " ";
bool isNullOrEmpty = text4.IsNullOrEmpty(); // 返回 false
// 设置默认值
string nullText = null;
string result = nullText.DefaultIfEmpty("N/A"); // 返回 "N/A"
类型转换
// 字符串转整数
string numText = "123";
int num = numText.ToInt(); // 返回 123
// 自动处理非数字字符
string mixedText = "a123b";
int num2 = mixedText.ToInt(); // 返回 123
// 转换失败时使用默认值
string invalidText = "abc";
int num3 = invalidText.ToInt(10); // 返回 10
// 转换为其他数值类型
string longText = "9876543210";
long longNum = longText.ToLong();
string shortText = "123";
short shortNum = shortText.ToShort();
字节数组扩展方法 (ByteExtensions)
编码转换
// 转换为Base64字符串
byte[] data = Encoding.UTF8.GetBytes("Hello World");
string base64 = data.ToBase64String(); // 返回 "SGVsbG8gV29ybGQ="
// 转换为十六进制字符串
byte[] bytes = { 0xFF, 0x00, 0xAB };
string hex = bytes.ToHexString(); // 返回 "FF00AB"
string hexLower = bytes.ToHexStringLower(); // 返回 "ff00ab"
// 转换为URL安全的Base64
byte[] urlData = Encoding.UTF8.GetBytes("Hello+World/=");
string urlSafe = urlData.ToUrlSafeBase64(); // 返回不含+、/和=的Base64字符串
// 转换为UTF-8字符串
byte[] utf8Bytes = Encoding.UTF8.GetBytes("Hello 世界");
string text = utf8Bytes.ToUtf8String(); // 返回 "Hello 世界"
哈希计算
// 计算HMAC-SHA1
byte[] data = Encoding.UTF8.GetBytes("重要数据");
string key = "secret-key";
byte[] hmacBytes = data.ToHmacSha1(key);
// 转换为Base64用于存储或传输
string signature = Convert.ToBase64String(hmacBytes);
文件路径处理方法
// 获取文件名
string filePath = @"C:\Users\Username\Documents\report.pdf";
string fileName = filePath.GetFileName(); // 返回 "report.pdf"
// 获取文件扩展名
string extension = filePath.GetExtension(); // 返回 ".pdf"
// 获取目录名
string directory = filePath.GetDirectoryName(); // 返回 "C:\Users\Username\Documents"
// 从右侧截取字符串
string text = "Hello World";
string right = text.Right(5); // 返回 "World"
// 组合路径
string basePath = @"C:\Users\Username";
string fullPath = basePath.CombinePath("Documents", "Projects", "MyApp");
// 返回 "C:\Users\Username\Documents\Projects\MyApp"
日期时间扩展方法 (DateTimeExtensions)
格式化
// 根据与当前日期的关系格式化日期
DateTime now = DateTime.Now;
string formatted = now.ToFriendlyDateString(); // 返回如 "14:30"
DateTime yesterday = DateTime.Now.AddDays(-1);
string formatted2 = yesterday.ToFriendlyDateString(); // 返回如 "12日 14:30"
// 日志格式化
string logTime = now.ToLogFormat(); // 返回 "2023-12-20 14:30:45"
string logTimeWithMs = now.ToLogFormat(true); // 返回 "2023-12-20 14:30:45.123"
// 友好日期格式化
// 今天的日期会显示为 "14:30"
// 昨天的日期会显示为 "12日 14:30"
// 上个月的日期会显示为 "5月12日 14:30"
// 去年的日期会显示为 "23年5月12日 14:30"
// 获取月份的开始和结束日期
DateTime date = new DateTime(2023, 5, 15);
DateTime firstDay = date.StartOfMonth(); // 返回 2023-05-01 00:00:00
DateTime lastDay = date.EndOfMonth(); // 返回 2023-05-31 23:59:59
日期计算
// 获取日期的开始和结束时间
DateTime date = DateTime.Now;
DateTime dayStart = date.StartOfDay(); // 返回当天 00:00:00.000
DateTime dayEnd = date.EndOfDay(); // 返回当天 23:59:59.999
// 获取周、月、季度、年的开始和结束
DateTime weekStart = date.StartOfWeek(); // 返回本周一 00:00:00.000
DateTime monthStart = date.StartOfMonth(); // 返回本月1日 00:00:00.000
DateTime monthEnd = date.EndOfMonth(); // 返回本月最后一天 23:59:59.999
DateTime quarterStart = date.StartOfQuarter(); // 返回本季度第一天 00:00:00.000
DateTime yearStart = date.StartOfYear(); // 返回本年1月1日 00:00:00.000
// 工作日判断
bool isWorkday = date.IsWeekday(); // 如果是周一至周五返回true
bool isWeekend = date.IsWeekend(); // 如果是周六或周日返回true
// 日期差异计算
DateTime futureDate = DateTime.Now.AddDays(10);
int daysUntil = DateTime.Now.DaysUntil(futureDate); // 返回10
// Unix时间戳转换
long timestamp = date.ToUnixTimestamp(); // 返回Unix时间戳(秒)
long timestampMs = date.ToUnixTimestampMs(); // 返回Unix时间戳(毫秒)
整型扩展方法 (IntExtensions)
范围检查和限制
// 判断数值是否在指定范围内
int age = 25;
bool isAdult = age.Between(18, 100); // 返回 true
// 限制数值在指定范围内
int score = 150;
int clampedScore = score.Clamp(0, 100); // 返回 100
int volume = -5;
int safeVolume = volume.Clamp(0, 100); // 返回 0
重复执行操作
// 重复执行指定次数的操作
5.Times(i => Console.WriteLine($"第 {i + 1} 次执行"));
// 创建测试数据
var items = new List<string>();
3.Times(i => items.Add($"Item {i + 1}")); // 添加3个元素到列表
// 批量处理
10.Times(i => ProcessBatch(i)); // 执行10次批处理操作
时间转换
// 将整数转换为TimeSpan
int timeout = 30; // 30秒
TimeSpan timeoutSpan = timeout.Seconds();
int cacheMinutes = 15;
TimeSpan expiry = cacheMinutes.Minutes();
int sessionHours = 2;
TimeSpan session = sessionHours.Hours();
int retentionDays = 30;
TimeSpan retention = retentionDays.Days();
数值格式化和判断
// 转换为二进制和十六进制字符串
int number = 10;
string binary = number.ToBinary(); // 返回 "1010"
int color = 255;
string hex = color.ToHexString(); // 返回 "FF"
string hexLower = color.ToHexString(false); // 返回 "ff"
// 判断奇偶性
int value = 42;
bool isEven = value.IsEven(); // 返回 true
bool isOdd = value.IsOdd(); // 返回 false
// 重复执行操作
var items = new List<string>();
5.Times(i => items.Add($"Item {i + 1}")); // 添加5个项目到列表
长整型扩展方法 (LongExtensions)
文件大小格式化
// 格式化文件大小
long fileSize = 1536;
string size1 = fileSize.ToFileSizeString(); // 返回 "1.50 KB"
string size2 = fileSize.ToFileSizeString(0); // 返回 "2 KB"
long largeSize = 1073741824;
string size3 = largeSize.ToFileSizeString(); // 返回 "1.00 GB"
时间戳转换
// Unix时间戳转换为DateTime
long timestamp = 1609459200; // 2021-01-01 00:00:00 UTC
DateTime date = timestamp.FromUnixTimestamp();
// 毫秒时间戳转换
long timestampMs = 1609459200000; // 2021-01-01 00:00:00.000 UTC
DateTime dateMs = timestampMs.FromUnixTimestampMs();
其他操作
// 范围检查和限制
long score = 85;
bool isPassing = score.Between(60, 100); // 返回 true
long value = 150;
long clampedValue = value.Clamp(0, 100); // 返回 100
// 毫秒转TimeSpan
long duration = 5000; // 5秒
TimeSpan timeSpan = duration.ToTimeSpan();
// 判断奇偶性
long number = 42;
bool isEven = number.IsEven(); // 返回 true
bool isOdd = number.IsOdd(); // 返回 false
JsonNode扩展方法 (JsonNodeExtensions)
// 将JsonNode转换为对象,如果是空数组则返回null
JsonNode? node = JsonNode.Parse("{\"name\":\"test\"}");
User? user = node.ToObjectOrNull<User>(JsonContext.Default.User);
// 处理空数组情况
JsonNode? emptyArray = JsonNode.Parse("[]");
User? nullUser = emptyArray.ToObjectOrNull<User>(JsonContext.Default.User); // 返回null
显示文本处理方法 (StringExtensions)
// 将无效值转换为默认显示文本
string birth = "0000-00-00 00:00:00";
string displayText = birth.ToDisplayText(["0000-00-00 00:00:00"], "暂无数据"); // 返回 "暂无数据"
string nullValue = null;
string displayText2 = nullValue.ToDisplayText("N/A", "暂无数据"); // 返回 "暂无数据"
// 日期显示文本处理
string dateStr = "2023-05-15";
string formattedDate = dateStr.ToDateDisplayText(); // 返回 "2023-05-15"
string invalidDate = "0000-00-00";
string formattedInvalidDate = invalidDate.ToDateDisplayText(); // 返回 "暂无数据"
string customFormatDate = "2023-05-15";
string formattedCustomDate = customFormatDate.ToDateDisplayText("无", "yyyy年MM月dd日"); // 返回 "2023年05月15日"
// 数字格式化显示
string number = "1234567.89";
string formattedNumber = number.ToFormattedNumber(2); // 返回 "1,234,567.89"
string formattedCurrency = number.ToFormattedNumber("C2"); // 返回 "¥1,234,567.89"
// 文件大小友好显示
string fileSize = "1048576";
string readableSize = fileSize.ToReadableFileSize(); // 返回 "1.00 MB"
// 枚举友好文本显示
var statusMappings = new Dictionary<string, string>
{
{"0", "禁用"},
{"1", "启用"},
{"2", "维护中"}
};
string statusCode = "1";
string friendlyStatus = statusCode.ToFriendlyText(statusMappings); // 返回 "启用"
// 条件格式化文本
string status = "1";
string display = status.ConditionalText(s => s == "1", "启用", "禁用"); // 返回 "启用"
// 将字符串转换为标题格式(每个单词首字母大写)
string text = "hello world";
string title = text.ToTitleCase(); // 返回 "Hello World"
string mixed = "tHIS iS a TeST";
string titleMixed = mixed.ToTitleCase(); // 返回 "This Is A Test"
字典扩展方法 (DictionaryExtensions)
// 定义枚举
public enum MemberStatus
{
Inactive = 0,
Active = 1,
Suspended = 2,
Premium = 3
}
public enum OrderType
{
Online = 1,
Offline = 2,
Wholesale = 3
}
public enum PaymentMethod
{
Cash,
Card,
Alipay,
WeChat
}
public enum Gender
{
Unknown = 0,
Male = 1,
Female = 2
}
public enum SortOrder
{
Asc,
Desc
}
var businessParams = new Dictionary<string, object>
{
["member_id"] = memberId
}
.AddIfNotEmpty("keywords", keywords)
.AddIfGreaterThan("page", page)
.AddIfGreaterThan("pagesize", pagesize)
// ✨ 枚举转数字
.AddIfValid("status", status,
s => s.HasValue,
s => (int)s!.Value)
// ✨ 枚举转自定义字符串
.AddIfValid("order_type", orderType,
t => t.HasValue,
t => t!.Value switch
{
OrderType.Online => "online_order",
OrderType.Offline => "offline_order",
OrderType.Wholesale => "wholesale_order",
_ => "unknown"
})
// ✨ 枚举转API代码
.AddIfValid("payment_method", paymentMethod,
p => p.HasValue,
p => p!.Value switch
{
PaymentMethod.Cash => "CASH_001",
PaymentMethod.Card => "CARD_002",
PaymentMethod.Alipay => "ALIPAY_003",
PaymentMethod.WeChat => "WECHAT_004",
_ => "UNKNOWN_000"
})
// ✨ 有条件的枚举转换(只有非Unknown时才添加)
.AddIfValid("gender", gender,
g => g.HasValue && g.Value != Gender.Unknown,
g => (int)g!.Value)
// ✨ 枚举转布尔值
.AddIfValid("is_desc", sortOrder,
s => s.HasValue,
s => s!.Value == SortOrder.Desc)
// ✨ 布尔值转数字
.AddIfValid("is_vip", isVip,
v => v.HasValue,
v => v!.Value ? 1 : 0)
// ✨ 布尔值转字符串
.AddIfValid("include_deleted", includeDeleted,
d => d.HasValue,
d => d!.Value ? "yes" : "no")
// ✨ 复杂条件 + 多重转换
.AddIfValid("priority_level", status,
s => s.HasValue && (s.Value == MemberStatus.Premium || s.Value == MemberStatus.Active),
s => s!.Value switch
{
MemberStatus.Premium => 100,
MemberStatus.Active => 50,
_ => 0
})
// ✨ 日期时间转时间戳
.AddIfValid("created_after_timestamp", createdAfter,
d => d.HasValue && d.Value > DateTime.MinValue,
d => ((DateTimeOffset)d!.Value).ToUnixTimeSeconds())
// ✨ 组合条件:只有VIP且状态为Active时才添加特殊标识
.AddIfValid("special_flag", status,
s => s.HasValue && s.Value == MemberStatus.Premium && isVip == true,
s => "VIP_PREMIUM")
// ✨ 多枚举组合逻辑
.AddIfValid("service_level", new { Status = status, OrderType = orderType },
combo => combo.Status.HasValue && combo.OrderType.HasValue,
combo => (combo.Status!.Value, combo.OrderType!.Value) switch
{
(MemberStatus.Premium, OrderType.Wholesale) => "enterprise",
(MemberStatus.Premium, _) => "premium",
(MemberStatus.Active, OrderType.Wholesale) => "business",
(MemberStatus.Active, _) => "standard",
_ => "basic"
});
// 转换为查询字符串
var queryString = businessParams.ToQueryString();
// 转换为 JSON
var jsonString = businessParams.ToJsonString();
更多方法查看代码文档。
字典扩展方法 (日期类型更多示例)
var parameters = new Dictionary<string, object>();
// 使用 List<string>
var dateList = new List<string> { "2024-01-01 00:00:00", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", dateList);
// 使用 string[]
var dateArray = new string[] { "2024-01-01 00:00:00", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", dateArray);
// 使用 IEnumerable<string>
IEnumerable<string> dateEnumerable = new[] { "2024-01-01 00:00:00", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", dateEnumerable);
// 空集合 - 不会添加
List<string>? emptyList = null;
parameters.AddIfValidDateRange("create_time", emptyList);
// 只有一个元素 - 不会添加
var singleDate = new List<string> { "2024-01-01 00:00:00" };
parameters.AddIfValidDateRange("create_time", singleDate);
// 超过两个元素 - 不会添加
var threeDates = new List<string> { "2024-01-01", "2024-01-15", "2024-01-31" };
parameters.AddIfValidDateRange("create_time", threeDates);
Console.WriteLine(parameters.ToQueryString());
// 输出: create_time=2024-01-01%2000%3A00%3A00&create_time=2024-01-31%2023%3A59%3A59
var parameters = new Dictionary<string, object>();
// 有效的日期时间格式 - 会添加
var validDates = new List<string> { "2024-01-01 00:00:00", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", validDates, validateDateTime: true);
// 无效的日期时间格式 - 不会添加
var invalidDates = new List<string> { "invalid-date", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", invalidDates, validateDateTime: true);
// 包含空字符串 - 不会添加
var emptyStringDates = new List<string> { "", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRange("create_time", emptyStringDates, validateDateTime: true);
// 不验证格式(默认行为)- 会添加任何两个字符串
var anyStrings = new List<string> { "任意字符串1", "任意字符串2" };
parameters.AddIfValidDateRange("create_time", anyStrings, validateDateTime: false);
Console.WriteLine(parameters.ToQueryString());
var parameters = new Dictionary<string, object>();
// 正确的时间顺序 - 会添加
var correctOrder = new List<string> { "2024-01-01 00:00:00", "2024-01-31 23:59:59" };
parameters.AddIfValidDateRangeWithOrder("create_time", correctOrder);
// 相同的时间 - 会添加
var sameTime = new List<string> { "2024-01-15 12:00:00", "2024-01-15 12:00:00" };
parameters.AddIfValidDateRangeWithOrder("update_time", sameTime);
// 错误的时间顺序 - 不会添加
var wrongOrder = new List<string> { "2024-01-31 23:59:59", "2024-01-01 00:00:00" };
parameters.AddIfValidDateRangeWithOrder("create_time", wrongOrder);
// 无效的日期格式 - 不会添加
var invalidFormat = new List<string> { "2024-13-01", "2024-01-32" };
parameters.AddIfValidDateRangeWithOrder("create_time", invalidFormat);
Console.WriteLine(parameters.ToQueryString());
字典扩展方法 (索引数组的示例)
// 支持 List<string>
var couponIds = new List<string> { "123", "456", "789" };
businessParams.AddIndexedArray("coupon_id", couponIds);
/* 结果:
coupon_id[0] = "123"
coupon_id[1] = "456"
coupon_id[2] = "789"
*/
// 支持 string[]
var couponArray = new[] { "123", "456", "789" };
businessParams.AddIndexedArray("coupon_id", couponArray);
/* 结果:
coupon_id[0] = "123"
coupon_id[1] = "456"
coupon_id[2] = "789"
*/
// 支持 IList<string>
IList<string> couponIList = new List<string> { "123", "456", "789" };
businessParams.AddIndexedArray("coupon_id", couponIList);
/* 结果:
coupon_id[0] = "123"
coupon_id[1] = "456"
coupon_id[2] = "789"
*/
// 支持 int[]
var categoryIds = new[] { 1, 2, 3 };
businessParams.AddIndexedArray("category_id", categoryIds);
/* 结果:
category_id[0] = 1
category_id[1] = 2
category_id[2] = 3
*/
// 支持 List<int>
var productIds = new List<int> { 100, 200, 300, 400 };
businessParams.AddIndexedArray("product_id", productIds);
/* 结果:
product_id[0] = 100
product_id[1] = 200
product_id[2] = 300
product_id[3] = 400
*/
// 支持 IList<int>
IList<int> orderIds = new List<int> { 10, 20, 30 };
businessParams.AddIndexedArray("order_id", orderIds);
/* 结果:
order_id[0] = 10
order_id[1] = 20
order_id[2] = 30
*/
// 支持 long[]
var userIds = new long[] { 1000000001L, 1000000002L, 1000000003L };
businessParams.AddIndexedArray("user_id", userIds);
/* 结果:
user_id[0] = 1000000001
user_id[1] = 1000000002
user_id[2] = 1000000003
*/
// 支持 List<long>
var transactionIds = new List<long> { 9999999999L, 8888888888L };
businessParams.AddIndexedArray("transaction_id", transactionIds);
/* 结果:
transaction_id[0] = 9999999999
transaction_id[1] = 8888888888
*/
// 单个元素
var singleCoupon = new[] { "SINGLE001" };
businessParams.AddIndexedArray("coupon_id", singleCoupon);
/* 结果:
coupon_id[0] = "SINGLE001"
*/
// 带条件检查,自动过滤空值
var mixedIds = new[] { "123", "", "456", null };
businessParams.AddIndexedArrayIfNotEmpty("coupon_id", mixedIds);
/* 结果(空字符串和null被过滤):
coupon_id[0] = "123"
coupon_id[1] = "456"
*/
// List<string> 过滤空值
var mixedCouponList = new List<string> { "C001", " ", "C002", null, "C003" };
businessParams.AddIndexedArrayIfNotEmpty("coupon_id", mixedCouponList);
/* 结果(空白字符串和null被过滤):
coupon_id[0] = "C001"
coupon_id[1] = "C002"
coupon_id[2] = "C003"
*/
// IList<string> 过滤空值
IList<string> mixedTagIds = new List<string> { "tag1", "", "tag2", null, "tag3" };
businessParams.AddIndexedArrayIfNotEmpty("tag_id", mixedTagIds);
/* 结果(空值被过滤):
tag_id[0] = "tag1"
tag_id[1] = "tag2"
tag_id[2] = "tag3"
*/
// int[] 条件添加
var validCategoryIds = new[] { 1, 2, 3 };
businessParams.AddIndexedArrayIfNotEmpty("category_id", validCategoryIds);
/* 结果:
category_id[0] = 1
category_id[1] = 2
category_id[2] = 3
*/
// List<int> 条件添加
var validIds = new List<int> { 10, 20, 30 };
businessParams.AddIndexedArrayIfNotEmpty("id", validIds);
/* 结果:
id[0] = 10
id[1] = 20
id[2] = 30
*/
// 数值范围验证 - 所有值都大于0
var ids = new[] { 1, 2, 3 };
businessParams.AddIndexedArrayIfAllGreaterThan("id", ids, 0);
/* 结果(所有值都大于0,全部添加):
id[0] = 1
id[1] = 2
id[2] = 3
*/
// 数值范围验证 - 包含无效值(包含0或负数)
var invalidIds = new[] { 1, 0, 3, -1 };
businessParams.AddIndexedArrayIfAllGreaterThan("id", invalidIds, 0);
/* 结果(因为包含<=0的值,整个数组不会被添加):
无任何参数添加
*/
// List<int> 数值范围验证 - 全部有效
var validCategoryIds2 = new List<int> { 5, 10, 15, 20 };
businessParams.AddIndexedArrayIfAllGreaterThan("category_id", validCategoryIds2, 0);
/* 结果(所有值都大于0):
category_id[0] = 5
category_id[1] = 10
category_id[2] = 15
category_id[3] = 20
*/
// List<int> 数值范围验证 - 包含无效值
var mixedCategoryIds = new List<int> { 5, 10, 0, 20 };
businessParams.AddIndexedArrayIfAllGreaterThan("category_id", mixedCategoryIds, 0);
/* 结果(包含0,整个数组不会被添加):
无任何参数添加
*/
// 自定义最小值验证
var priceIds = new[] { 100, 200, 300 };
businessParams.AddIndexedArrayIfAllGreaterThan("price_id", priceIds, 50);
/* 结果(所有值都大于50):
price_id[0] = 100
price_id[1] = 200
price_id[2] = 300
*/
// null 数组处理
string[]? nullArray = null;
businessParams.AddIndexedArray("coupon_id", nullArray);
/* 结果(null被忽略):
无任何参数添加
*/
// null 列表处理
List<string>? nullList = null;
businessParams.AddIndexedArrayIfNotEmpty("coupon_id", nullList);
/* 结果(null被忽略):
无任何参数添加
*/
// 空数组处理
var emptyArray = new string[] { };
businessParams.AddIndexedArray("coupon_id", emptyArray);
/* 结果(空数组被忽略):
无任何参数添加
*/
// 空列表处理
var emptyList = new List<string>();
businessParams.AddIndexedArrayIfNotEmpty("coupon_id", emptyList);
/* 结果(空列表被忽略):
无任何参数添加
*/
// 全部为null或空字符串的数组
var allEmptyArray = new[] { "", null, " ", null };
businessParams.AddIndexedArrayIfNotEmpty("coupon_id", allEmptyArray);
/* 结果(所有元素都被过滤):
无任何参数添加
*/
// 多种类型组合使用
var comboCouponIds = new List<string> { "C001", "C002", "C003" };
var comboCategoryIds = new[] { 10, 20, 30 };
var comboTagIds = new[] { "hot", "", "new", null, "sale" };
var comboUserIds = new long[] { 1000001L, 1000002L };
var comboValidIds = new[] { 1, 2, 3 };
var comboInvalidIds = new[] { 1, 0, 3 };
var businessParams = new Dictionary<string, object>
{
["member_id"] = 12345,
["action"] = "batch_operation"
}
.AddIndexedArray("coupon_id", comboCouponIds)
.AddIndexedArray("category_id", comboCategoryIds)
.AddIndexedArrayIfNotEmpty("tag_id", comboTagIds)
.AddIndexedArray("user_id", comboUserIds)
.AddIndexedArrayIfAllGreaterThan("valid_id", comboValidIds, 0)
.AddIndexedArrayIfAllGreaterThan("invalid_id", comboInvalidIds, 0);
/* 完整结果:
member_id = 12345
action = "batch_operation"
coupon_id[0] = "C001"
coupon_id[1] = "C002"
coupon_id[2] = "C003"
category_id[0] = 10
category_id[1] = 20
category_id[2] = 30
tag_id[0] = "hot"
tag_id[1] = "new"
tag_id[2] = "sale"
user_id[0] = 1000001
user_id[1] = 1000002
valid_id[0] = 1
valid_id[1] = 2
valid_id[2] = 3
(invalid_id不会被添加,因为包含0)
*/
// 实际业务方法使用
var memberCouponIds = new List<string> { "CPN001", "CPN002", "CPN003" };
var businessParams2 = new Dictionary<string, object>
{
["member_id"] = 12345,
}
.AddIndexedArrayIfNotEmpty("coupon_id", memberCouponIds);
/* businessParams2 结果:
member_id = 12345
coupon_id[0] = "CPN001"
coupon_id[1] = "CPN002"
coupon_id[2] = "CPN003"
*/
// 包含特殊字符的字符串
var specialCoupons = new[] { "COUP&ON1", "COUP=ON2", "COUP ON3" };
businessParams.AddIndexedArray("coupon_id", specialCoupons);
/* 结果:
coupon_id[0] = "COUP&ON1"
coupon_id[1] = "COUP=ON2"
coupon_id[2] = "COUP ON3"
查询字符串(URL编码后):
coupon_id[0]=COUP%26ON1&coupon_id[1]=COUP%3DON2&coupon_id[2]=COUP%20ON3
*/
// 中文字符处理
var chineseCoupons = new[] { "优惠券1", "优惠券2" };
businessParams.AddIndexedArray("coupon_id", chineseCoupons);
/* 结果:
coupon_id[0] = "优惠券1"
coupon_id[1] = "优惠券2"
*/
// 超长数组
var longArray = new string[100];
for (int i = 0; i < 100; i++) { longArray[i] = $"item{i}"; }
businessParams.AddIndexedArray("items", longArray);
/* 结果:
items[0] = "item0"
items[1] = "item1"
...
items[99] = "item99"
查询字符串:
items[0]=item0&items[1]=item1&...&items[99]=item99
*/
// 混合类型在同一字典中
var mixedBusinessParams = new Dictionary<string, object>
{
["user_id"] = 999,
["status"] = "active"
}
.AddIndexedArray("coupon_ids", new[] { "A", "B", "C" })
.AddIndexedArray("category_ids", new[] { 1, 2, 3 })
.AddIndexedArrayIfNotEmpty("tag_ids", new[] { "hot", "", "new" })
.AddIndexedArrayIfAllGreaterThan("price_ranges", new[] { 100, 200, 300 }, 50);
/* 结果:
user_id = 999
status = "active"
coupon_ids[0] = "A"
coupon_ids[1] = "B"
coupon_ids[2] = "C"
category_ids[0] = 1
category_ids[1] = 2
category_ids[2] = 3
tag_ids[0] = "hot"
tag_ids[1] = "new"
price_ranges[0] = 100
price_ranges[1] = 200
price_ranges[2] = 300
字典扩展方法 (字典类型的转换) DEMO
using System;
using System.Collections.Generic;
using Sage.Data.Extensions;
namespace DictionaryExtensionsExamples
{
class Program
{
static void Main()
{
Console.WriteLine("=== 字典扩展方法使用示例 ===\n");
// ========================================
// 1. 基础值类型转换方法
// ========================================
Console.WriteLine("【1. 基础值类型转换】");
BasicTypeConversion();
// ========================================
// 2. 键类型转换方法
// ========================================
Console.WriteLine("\n【2. 键类型转换】");
KeyTypeConversion();
// ========================================
// 3. Dictionary 与 SortedDictionary 相互转换
// ========================================
Console.WriteLine("\n【3. Dictionary 与 SortedDictionary 相互转换】");
DictionarySortedDictionaryConversion();
// ========================================
// 4. 常用类型转换便捷方法
// ========================================
Console.WriteLine("\n【4. 常用类型转换便捷方法】");
CommonTypeConversions();
// ========================================
// 5. 常用排序场景的便捷方法
// ========================================
Console.WriteLine("\n【5. 常用排序场景】");
SortingScenarios();
// ========================================
// 6. 高级转换方法
// ========================================
Console.WriteLine("\n【6. 高级转换方法】");
AdvancedConversions();
Console.WriteLine("\n=== 示例结束 ===");
Console.ReadKey();
}
// ========================================
// 1. 基础值类型转换方法
// ========================================
static void BasicTypeConversion()
{
// 1.1 ToDictionary<TValue> - 基础转换
Console.WriteLine("1.1 ToDictionary<TValue> - 基础转换");
var source1 = new Dictionary<string, object>
{
{ "age", 25 },
{ "score", "100" }, // 字符串会被自动转换为int
{ "level", 5 }
};
var intDict = source1.ToDictionary<int>();
Console.WriteLine($" age={intDict["age"]}, score={intDict["score"]}, level={intDict["level"]}");
// 1.2 ToSortedDictionary<TValue> - SortedDictionary 转换
Console.WriteLine("\n1.2 ToSortedDictionary<TValue> - SortedDictionary 转换");
var sortedSource = new SortedDictionary<string, object>
{
{ "price", 99.99m },
{ "discount", "10.5" } // 字符串转为decimal
};
var decimalSorted = sortedSource.ToSortedDictionary<decimal>();
foreach (var kvp in decimalSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 1.3 ToDictionarySafe<TValue> - 安全转换(跳过失败的项)
Console.WriteLine("\n1.3 ToDictionarySafe<TValue> - 安全转换");
var mixedSource = new Dictionary<string, object>
{
{ "age", 25 },
{ "name", "John" }, // 这个无法转为int,会被跳过
{ "score", 100 },
{ "address", "Beijing" } // 这个也会被跳过
};
var safeIntDict = mixedSource.ToDictionarySafe<int>();
Console.WriteLine($" 成功转换的项数: {safeIntDict.Count}");
foreach (var kvp in safeIntDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 1.4 ToSortedDictionarySafe<TValue> - SortedDictionary 安全转换
Console.WriteLine("\n1.4 ToSortedDictionarySafe<TValue> - SortedDictionary 安全转换");
var mixedSorted = new SortedDictionary<string, object>
{
{ "count", 10 },
{ "description", "测试" },
{ "total", "50" }
};
var safeIntSorted = mixedSorted.ToSortedDictionarySafe<int>();
Console.WriteLine($" 成功转换的项数: {safeIntSorted.Count}");
foreach (var kvp in safeIntSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 1.5 ToDictionary<TValue>(defaultValue) - 带默认值的转换
Console.WriteLine("\n1.5 ToDictionary<TValue>(defaultValue) - 带默认值转换");
var withDefault = mixedSource.ToDictionary<int>(0);
Console.WriteLine($" 转换后的项数: {withDefault.Count}");
foreach (var kvp in withDefault)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 1.6 ToSortedDictionary<TValue>(defaultValue) - SortedDictionary 带默认值
Console.WriteLine("\n1.6 ToSortedDictionary<TValue>(defaultValue) - 带默认值");
var sortedWithDefault = mixedSorted.ToSortedDictionary<int>(-1);
foreach (var kvp in sortedWithDefault)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
// ========================================
// 2. 键类型转换方法
// ========================================
static void KeyTypeConversion()
{
// 2.1 ToDictionary<TKey, TValue>(keyConverter) - 键转换
Console.WriteLine("2.1 ToDictionary<TKey, TValue>(keyConverter) - 键转换");
var stringKeyDict = new Dictionary<string, object>
{
{ "1", 100 },
{ "2", 200 },
{ "10", 1000 }
};
var intKeyDict = stringKeyDict.ToDictionary<int, int>(key => int.Parse(key));
foreach (var kvp in intKeyDict)
{
Console.WriteLine($" Key={kvp.Key} (int), Value={kvp.Value}");
}
// 2.2 ToDictionary<TKey, TValue>(keyConverter, valueConverter) - 键值同时转换
Console.WriteLine("\n2.2 ToDictionary<TKey, TValue> - 键值同时转换");
var allStringDict = new Dictionary<string, object>
{
{ "100", "10.5" },
{ "200", "20.8" },
{ "300", "30.2" }
};
var convertedDict = allStringDict.ToDictionary<int, decimal>(
key => int.Parse(key),
value => decimal.Parse(value.ToString()!)
);
foreach (var kvp in convertedDict)
{
Console.WriteLine($" Key={kvp.Key} (int), Value={kvp.Value} (decimal)");
}
// 2.3 ToSortedDictionary<TKey, TValue>(keyConverter) - SortedDictionary 键转换
Console.WriteLine("\n2.3 ToSortedDictionary<TKey, TValue>(keyConverter)");
var sortedStringKey = new SortedDictionary<string, object>
{
{ "5", "Apple" },
{ "2", "Banana" },
{ "8", "Cherry" }
};
var sortedIntKey = sortedStringKey.ToSortedDictionary<int, string>(
key => int.Parse(key)
);
Console.WriteLine(" 排序后的结果:");
foreach (var kvp in sortedIntKey)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 2.4 ToSortedDictionary<TKey, TValue>(keyConverter, valueConverter) - 完整转换
Console.WriteLine("\n2.4 ToSortedDictionary<TKey, TValue> - 键值完整转换");
var fullConvert = new SortedDictionary<string, object>
{
{ "10", "100.5" },
{ "5", "50.2" },
{ "15", "150.8" }
};
var fullConverted = fullConvert.ToSortedDictionary<int, double>(
key => int.Parse(key),
value => double.Parse(value.ToString()!)
);
foreach (var kvp in fullConverted)
{
Console.WriteLine($" {kvp.Key} => {kvp.Value}");
}
}
// ========================================
// 3. Dictionary 与 SortedDictionary 相互转换
// ========================================
static void DictionarySortedDictionaryConversion()
{
// 3.1 ToSortedDictionary() - Dictionary 转 SortedDictionary
Console.WriteLine("3.1 ToSortedDictionary() - Dictionary 转 SortedDictionary");
var unsortedDict = new Dictionary<string, object>
{
{ "zebra", 3 },
{ "apple", 1 },
{ "banana", 2 }
};
var sorted = unsortedDict.ToSortedDictionary();
Console.WriteLine(" 排序后:");
foreach (var kvp in sorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 3.2 ToDictionary() - SortedDictionary 转 Dictionary
Console.WriteLine("\n3.2 ToDictionary() - SortedDictionary 转 Dictionary");
var sortedDict = new SortedDictionary<string, object>
{
{ "a", 1 },
{ "b", 2 },
{ "c", 3 }
};
var normalDict = sortedDict.ToDictionary();
Console.WriteLine($" 转换后类型: {normalDict.GetType().Name}");
Console.WriteLine($" 项数: {normalDict.Count}");
// 3.3 ToSortedDictionary<TValue>() - 带类型转换的排序
Console.WriteLine("\n3.3 ToSortedDictionary<TValue> - 带类型转换排序");
var mixedDict = new Dictionary<string, object>
{
{ "z-score", "100" },
{ "a-level", 5 },
{ "m-count", "50" }
};
var sortedTyped = mixedDict.ToSortedDictionary<int>();
foreach (var kvp in sortedTyped)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 3.4 ToDictionary<TValue>() - SortedDictionary 带类型转换
Console.WriteLine("\n3.4 ToDictionary<TValue> - SortedDictionary 类型转换");
var typedSorted = new SortedDictionary<string, object>
{
{ "price", "99.99" },
{ "discount", 10.5m },
{ "tax", "5.5" }
};
var typedDict = typedSorted.ToDictionary<decimal>();
foreach (var kvp in typedDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value:F2}");
}
// 3.5 ToSortedDictionarySafe<TValue>() - 安全转换排序
Console.WriteLine("\n3.5 ToSortedDictionarySafe<TValue> - 安全转换排序");
var mixedForSafe = new Dictionary<string, object>
{
{ "valid1", 10 },
{ "invalid", "not a number" },
{ "valid2", 20 }
};
var safeSorted = mixedForSafe.ToSortedDictionarySafe<int>();
Console.WriteLine($" 成功转换: {safeSorted.Count} 项");
foreach (var kvp in safeSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 3.6 ToSortedDictionary<TKey, TValue>(keyConverter) - 键转换排序
Console.WriteLine("\n3.6 ToSortedDictionary<TKey, TValue> - 键转换排序");
var keyConvertDict = new Dictionary<string, object>
{
{ "3", "Three" },
{ "1", "One" },
{ "2", "Two" }
};
var keySorted = keyConvertDict.ToSortedDictionary<int, string>(
key => int.Parse(key)
);
foreach (var kvp in keySorted)
{
Console.WriteLine($" {kvp.Key} => {kvp.Value}");
}
// 3.7 ToSortedDictionary<TKey, TValue>(keyConverter, valueConverter) - 完整转换排序
Console.WriteLine("\n3.7 ToSortedDictionary<TKey, TValue> - 完整转换排序");
var fullDict = new Dictionary<string, object>
{
{ "100", "10.5" },
{ "50", "5.2" },
{ "200", "20.8" }
};
var fullSorted = fullDict.ToSortedDictionary<int, decimal>(
key => int.Parse(key),
value => decimal.Parse(value.ToString()!)
);
foreach (var kvp in fullSorted)
{
Console.WriteLine($" {kvp.Key} => {kvp.Value}");
}
// 3.8 自定义比较器示例
Console.WriteLine("\n3.8 使用自定义比较器(忽略大小写)");
var caseDict = new Dictionary<string, object>
{
{ "Name", 1 },
{ "age", 2 },
{ "ADDRESS", 3 }
};
var caseSorted = caseDict.ToSortedDictionary(StringComparer.OrdinalIgnoreCase);
foreach (var kvp in caseSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
// ========================================
// 4. 常用类型转换便捷方法
// ========================================
static void CommonTypeConversions()
{
// 4.1 ToStringDictionary() - 转为字符串字典
Console.WriteLine("4.1 ToStringDictionary() - 转为字符串字典");
var mixedDict = new Dictionary<string, object>
{
{ "age", 25 },
{ "price", 99.99m },
{ "active", true },
{ "date", DateTime.Now }
};
var stringDict = mixedDict.ToStringDictionary();
foreach (var kvp in stringDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value} (类型: {kvp.Value.GetType().Name})");
}
// 4.2 ToStringDictionary() - SortedDictionary 版本
Console.WriteLine("\n4.2 ToStringDictionary() - SortedDictionary 版本");
var sortedMixed = new SortedDictionary<string, object>
{
{ "count", 100 },
{ "name", "Test" },
{ "enabled", false }
};
var sortedString = sortedMixed.ToStringDictionary();
foreach (var kvp in sortedString)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 4.3 ToIntDictionary() - 转为整数字典
Console.WriteLine("\n4.3 ToIntDictionary() - 转为整数字典");
var numDict = new Dictionary<string, object>
{
{ "age", 25 },
{ "score", "100" },
{ "level", 5 }
};
var intDict = numDict.ToIntDictionary();
Console.WriteLine($" Total: {intDict.Values.Sum()}");
// 4.4 ToIntDictionary(defaultValue) - 带默认值
Console.WriteLine("\n4.4 ToIntDictionary(defaultValue) - 带默认值");
var mixedNum = new Dictionary<string, object>
{
{ "valid", 10 },
{ "invalid", "abc" },
{ "another", 20 }
};
var intWithDefault = mixedNum.ToIntDictionary(0);
foreach (var kvp in intWithDefault)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 4.5 ToLongDictionary() - 转为长整数字典
Console.WriteLine("\n4.5 ToLongDictionary() - 转为长整数字典");
var bigNumDict = new Dictionary<string, object>
{
{ "bignum1", 1000000000L },
{ "bignum2", "2000000000" }
};
var longDict = bigNumDict.ToLongDictionary();
foreach (var kvp in longDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value:N0}");
}
// 4.6 ToLongDictionary(defaultValue) - 带默认值
Console.WriteLine("\n4.6 ToLongDictionary(defaultValue) - 带默认值");
var mixedLong = new Dictionary<string, object>
{
{ "valid", 999999999999L },
{ "invalid", "not-a-number" }
};
var longWithDefault = mixedLong.ToLongDictionary(0L);
foreach (var kvp in longWithDefault)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 4.7 ToDecimalDictionary() - 转为小数字典
Console.WriteLine("\n4.7 ToDecimalDictionary() - 转为小数字典");
var priceDict = new Dictionary<string, object>
{
{ "price", 99.99m },
{ "discount", "10.5" },
{ "tax", 5.5 }
};
var decimalDict = priceDict.ToDecimalDictionary();
foreach (var kvp in decimalDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value:C}");
}
// 4.8 ToDecimalDictionary(defaultValue) - 带默认值
Console.WriteLine("\n4.8 ToDecimalDictionary(defaultValue) - 带默认值");
var mixedDecimal = new Dictionary<string, object>
{
{ "amount", 100.50m },
{ "invalid", "xyz" }
};
var decimalWithDefault = mixedDecimal.ToDecimalDictionary(0m);
foreach (var kvp in decimalWithDefault)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 4.9 ToBoolDictionary() - 转为布尔字典
Console.WriteLine("\n4.9 ToBoolDictionary() - 转为布尔字典");
var flagDict = new Dictionary<string, object>
{
{ "enabled", true },
{ "active", "true" },
{ "visible", false }
};
var boolDict = flagDict.ToBoolDictionary();
foreach (var kvp in boolDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 4.10 ToDateTimeDictionary() - 转为日期时间字典
Console.WriteLine("\n4.10 ToDateTimeDictionary() - 转为日期时间字典");
var dateDict = new Dictionary<string, object>
{
{ "created", DateTime.Now },
{ "modified", "2024-01-01" },
{ "expires", new DateTime(2025, 12, 31) }
};
var dateTimeDict = dateDict.ToDateTimeDictionary();
foreach (var kvp in dateTimeDict)
{
Console.WriteLine($" {kvp.Key}={kvp.Value:yyyy-MM-dd}");
}
// 4.11 ToGuidDictionary() - 转为 GUID 字典
Console.WriteLine("\n4.11 ToGuidDictionary() - 转为 GUID 字典");
var guid1 = Guid.NewGuid();
var guid2 = Guid.NewGuid();
var guidDict = new Dictionary<string, object>
{
{ "id1", guid1 },
{ "id2", guid2.ToString() }
};
var guidDictResult = guidDict.ToGuidDictionary();
foreach (var kvp in guidDictResult)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
// ========================================
// 5. 常用排序场景的便捷方法
// ========================================
static void SortingScenarios()
{
// 5.1 ToSortedStringDictionary() - 排序字符串字典
Console.WriteLine("5.1 ToSortedStringDictionary() - 排序字符串字典");
var unsorted = new Dictionary<string, object>
{
{ "name", "John" },
{ "age", 25 },
{ "city", "Beijing" }
};
var sortedString = unsorted.ToSortedStringDictionary();
Console.WriteLine(" 按键排序:");
foreach (var kvp in sortedString)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 5.2 ToSortedIntDictionary() - 排序整数字典
Console.WriteLine("\n5.2 ToSortedIntDictionary() - 排序整数字典");
var numUnsorted = new Dictionary<string, object>
{
{ "z-score", 100 },
{ "a-level", 5 },
{ "m-count", 50 }
};
var sortedInt = numUnsorted.ToSortedIntDictionary();
foreach (var kvp in sortedInt)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 5.3 ToSortedDictionaryIgnoreCase() - 忽略大小写排序
Console.WriteLine("\n5.3 ToSortedDictionaryIgnoreCase() - 忽略大小写排序");
var caseDict = new Dictionary<string, object>
{
{ "Name", 1 },
{ "age", 2 },
{ "ADDRESS", 3 },
{ "City", 4 }
};
var caseIgnoreSorted = caseDict.ToSortedDictionaryIgnoreCase();
Console.WriteLine(" 忽略大小写排序:");
foreach (var kvp in caseIgnoreSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 5.4 ToSortedDictionaryNatural() - 自然排序(数字感知)
Console.WriteLine("\n5.4 ToSortedDictionaryNatural() - 自然排序");
var naturalDict = new Dictionary<string, object>
{
{ "item10", "第10项" },
{ "item2", "第2项" },
{ "item1", "第1项" },
{ "item20", "第20项" },
{ "item3", "第3项" }
};
var naturalSorted = naturalDict.ToSortedDictionaryNatural();
Console.WriteLine(" 自然排序结果 (item1, item2, item3, item10, item20):");
foreach (var kvp in naturalSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 对比普通排序
Console.WriteLine("\n 对比: 普通字母排序 (item1, item10, item2, item20, item3):");
var normalSorted = naturalDict.ToSortedDictionary();
foreach (var kvp in normalSorted)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
// ========================================
// 6. 高级转换方法
// ========================================
static void AdvancedConversions()
{
// 6.1 ToDictionaryWhere<TValue>() - 条件过滤转换
Console.WriteLine("6.1 ToDictionaryWhere<TValue> - 条件过滤转换");
var mixedDict = new Dictionary<string, object>
{
{ "age", 25 },
{ "score", 100 },
{ "name", "John" },
{ "level", "5" },
{ "address", "Beijing" }
};
// 只转换可以转为 int 的项
var filteredInt = mixedDict.ToDictionaryWhere<int>(
kvp => kvp.Value is int ||
(kvp.Value is string s && int.TryParse(s, out _))
);
Console.WriteLine(" 只包含可转为int的项:");
foreach (var kvp in filteredInt)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 只转换值大于某个数的项
var filteredLarge = mixedDict.ToDictionaryWhere<int>(
kvp => {
if (kvp.Value is int i) return i > 50;
if (kvp.Value is string s && int.TryParse(s, out var n)) return n > 50;
return false;
}
);
Console.WriteLine("\n 只包含值大于50的项:");
foreach (var kvp in filteredLarge)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 6.2 TryToDictionary<TValue>() - 尝试转换
Console.WriteLine("\n6.2 TryToDictionary<TValue> - 尝试转换");
// 成功的转换
var validDict = new Dictionary<string, object>
{
{ "age", 25 },
{ "score", "100" },
{ "level", 5 }
};
if (validDict.TryToDictionary<int>(out var successResult))
{
Console.WriteLine(" ✓ 转换成功!");
Console.WriteLine($" 转换了 {successResult.Count} 项");
foreach (var kvp in successResult)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
}
else
{
Console.WriteLine(" ✗ 转换失败");
}
// 失败的转换
var invalidDict = new Dictionary<string, object>
{
{ "age", 25 },
{ "name", "John" }, // 这个无法转为int
{ "score", 100 }
};
if (invalidDict.TryToDictionary<int>(out var failResult))
{
Console.WriteLine("\n ✓ 转换成功");
}
else
{
Console.WriteLine("\n ✗ 转换失败 (包含无法转换的项)");
Console.WriteLine($" 结果字典项数: {failResult.Count}");
}
// 6.3 复杂场景组合示例
Console.WriteLine("\n6.3 复杂场景组合示例");
var complexDict = new Dictionary<string, object>
{
{ "100", "张三" },
{ "50", "李四" },
{ "200", "王五" },
{ "30", "赵六" }
};
// 先转换键为int,再排序,再过滤出ID大于50的
var complexResult = complexDict
.ToDictionary<int, string>(key => int.Parse(key)) // 键转为int
.Where(kvp => kvp.Key > 50) // 过滤
.OrderBy(kvp => kvp.Key) // 排序
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // 转回Dictionary
Console.WriteLine(" ID大于50的用户 (按ID排序):");
foreach (var kvp in complexResult)
{
Console.WriteLine($" ID={kvp.Key}, Name={kvp.Value}");
}
// 6.4 实际应用场景示例
Console.WriteLine("\n6.4 实际应用场景 - API参数处理");
var apiParams = new Dictionary<string, object>
{
{ "page", "1" },
{ "pageSize", 20 },
{ "keyword", "测试" },
{ "status", null }, // null 值
{ "startDate", "" }, // 空字符串
{ "categoryId", "5" }
};
// 转换为字符串字典,移除空值
var cleanParams = apiParams
.Where(kvp => kvp.Value != null &&
(kvp.Value is not string s || !string.IsNullOrWhiteSpace(s)))
.ToStringDictionary();
Console.WriteLine(" 清理后的API参数:");
foreach (var kvp in cleanParams)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 生成查询字符串
var queryString = string.Join("&",
cleanParams.Select(kvp => $"{kvp.Key}={kvp.Value}"));
Console.WriteLine($"\n 查询字符串: {queryString}");
}
// ========================================
// 额外示例:实际业务场景
// ========================================
static void RealWorldScenarios()
{
Console.WriteLine("\n【实际业务场景示例】");
// 场景1:配置文件处理
Console.WriteLine("\n场景1: 配置文件处理");
var config = new Dictionary<string, object>
{
{ "maxConnections", "100" },
{ "timeout", 30 },
{ "enableCache", "true" },
{ "cacheExpiration", "3600" }
};
var intConfig = config
.Where(kvp => kvp.Key.Contains("max") || kvp.Key.Contains("timeout") || kvp.Key.Contains("Expiration"))
.ToIntDictionary(0);
Console.WriteLine(" 整数配置项:");
foreach (var kvp in intConfig)
{
Console.WriteLine($" {kvp.Key}={kvp.Value}");
}
// 场景2:数据库查询结果转换
Console.WriteLine("\n场景2: 数据库查询结果转换");
var dbResult = new Dictionary<string, object>
{
{ "UserId", 1001 },
{ "UserName", "张三" },
{ "Age", "28" },
{ "Salary", "8500.50" },
{ "IsActive", true }
};
// 按需转换不同类型
var userId = dbResult.GetValueOrDefault<int>("UserId");
var userName = dbResult.GetValueOrDefault<string>("UserName", "");
var age = int.Parse(dbResult["Age"].ToString()!);
var salary = decimal.Parse(dbResult["Salary"].ToString()!);
Console.WriteLine($" 用户信息: ID={userId}, 姓名={userName}, 年龄={age}, 薪资={salary:C}");
// 场景3:商品分类排序
Console.WriteLine("\n场景3: 商品分类排序");
var categories = new Dictionary<string, object>
{
{ "category10", "电子产品" },
{ "category2", "图书" },
{ "category1", "食品" },
{ "category20", "服装" },
{ "category3", "家居" }
};
var sortedCategories = categories.ToSortedDictionaryNatural();
Console.WriteLine(" 自然排序的分类:");
foreach (var kvp in sortedCategories)
{
Console.WriteLine($" {kvp.Key} => {kvp.Value}");
}
// 场景4:多语言配置
Console.WriteLine("\n场景4: 多语言配置");
var i18n = new Dictionary<string, object>
{
{ "Welcome", "欢迎" },
{ "goodbye", "再见" },
{ "HELLO", "你好" },
{ "Thanks", "谢谢" }
};
var i18nSorted = i18n.ToSortedDictionaryIgnoreCase();
Console.WriteLine(" 忽略大小写排序的翻译:");
foreach (var kvp in i18nSorted)
{
Console.WriteLine($" {kvp.Key} => {kvp.Value}");
}
}
}
}
许可证
本项目采用 Apache 2.0 许可证。详情请参阅 LICENSE 文件。
贡献
欢迎提交问题报告和改进建议。如果您想贡献代码,请提交拉取请求。
作者
- LiuPengLai - 甲壳虫科技 欢迎提交问题和功能请求。 QQ Group: 1054304346
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Sage.Data.Extensions:
| Package | Downloads |
|---|---|
|
Sage.CloudStorage.Qiniu
Sage.CloudStorage.Qiniu 是一个基于 .NET 平台的现代化七牛云存储 SDK,采用完全异步设计,提供了对七牛云对象存储、CDN 等服务的简单易用的 API 封装。该库基于 Sage.Http 构建,具有高性能、可扩展的七牛云服务访问能力,特别适合企业级应用和大文件处理场景。 ## 核心优势 - **现代化API设计**:完全异步,符合.NET最佳实践 - **模块化架构**:各组件职责明确,易于扩展和维护 - **丰富的事件机制**:提供上传进度通知和完成事件 - **智能上传策略**:自动选择最佳上传方式和分片大小 - **完善的错误处理**:提供详细的错误信息和恢复机制 ## 功能特性 - **完整的对象存储支持**:上传、下载、管理、删除等操作 - **高级上传功能**: - 智能分片上传(自动优化分片大小) - 断点续传支持 - 并发控制 - 实时进度监控 - **CDN管理**:刷新、预取、带宽查询、日志下载 - **数据处理**:图片处理、音视频转码等 - **批量操作**:批量上传、删除等 |
|
|
Sage.Encryption
Sage.Encryption 提供了加密和解密功能,支持多种加密算法,支持Windows安全存储等。 - AES 加密/解密 - AES-GCM 加密/解密 - Windows 安全数据存储 - 同步和异步 API - 完全兼容 AOT 编译 |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 1.0.1.1 | 289 | 10/25/2025 | |
| 1.0.0.22 | 252 | 10/25/2025 | |
| 1.0.0.21 | 313 | 10/15/2025 | |
| 1.0.0.20 | 319 | 10/15/2025 | |
| 1.0.0.19 | 440 | 10/15/2025 | |
| 1.0.0.18 | 364 | 10/13/2025 | |
| 1.0.0.17 | 343 | 10/5/2025 | |
| 1.0.0.16 | 329 | 10/5/2025 | |
| 1.0.0.15 | 334 | 10/5/2025 | |
| 1.0.0.14 | 269 | 10/4/2025 | |
| 1.0.0.13 | 335 | 10/3/2025 | |
| 1.0.0.12 | 372 | 10/2/2025 | |
| 1.0.0.11 | 352 | 10/2/2025 | |
| 1.0.0.10 | 338 | 10/1/2025 | |
| 1.0.0.9 | 346 | 10/1/2025 | |
| 1.0.0.8 | 345 | 10/1/2025 | |
| 1.0.0.7 | 295 | 9/28/2025 | |
| 1.0.0.6 | 274 | 9/27/2025 | |
| 1.0.0.5 | 328 | 9/26/2025 | |
| 1.0.0.4 | 439 | 8/24/2025 |
丰富字典转换功能