保护与验证模式
使用保护子句及早验证输入,抛出正确的异常,并对用户数据使用 TryParse 风格的检查。
保护与验证模式 是 CoddyKit 上的免费 C# Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 3 节课。
为什么需要保护
目标:使方法安全且易读。
- 在开头使用保护子句
- 抛出特定异常(ArgumentNullException、ArgumentOutOfRangeException)
- 对用户输入使用 TryParse
- 快速失败;避免深层嵌套
提前保护示例
在开头添加小型检查来验证参数;抛出特定异常,让调用方知道出了什么问题。
using System;
// Demo: validate inputs at the top; keep main logic flat.
public class Program
{
// Compute price with simple rules; guard early.
public static decimal ComputePrice(string sku, int qty, decimal unitPrice)
{
if (sku == null) throw new ArgumentNullException("sku");
if (sku.Length == 0) throw new ArgumentException("sku must not be empty", "sku");
if (qty <= 0) throw new ArgumentOutOfRangeException("qty", "qty must be > 0");
if (unitPrice < 0m) throw new ArgumentOutOfRangeException("unitPrice", "unitPrice must be >= 0");
// Main logic stays simple
decimal subtotal = qty * unitPrice;
if (qty >= 10) subtotal = subtotal * 0.9m; // small bulk discount
return subtotal;
}
public static void Main(string[] args)
{
Console.WriteLine(ComputePrice("ABC", 2, 5m)); // ok
try { Console.WriteLine(ComputePrice("", 2, 5m)); } catch (Exception ex) { Console.WriteLine(ex.GetType().Name); }
}
}
Guard 辅助类
将常见检查提取到小型 Guard 类中,使方法体保持整洁且一致。
using System;
// Minimal static helper for common validations (beginner friendly).
public static class Guard
{
public static void NotNull(object value, string name)
{
if (value == null) throw new ArgumentNullException(name);
}
public static void NotNullOrEmpty(string value, string name)
{
if (value == null) throw new ArgumentNullException(name);
if (value.Length == 0) throw new ArgumentException(name + " must not be empty", name);
}
public static void InRange(int value, int minInclusive, int maxInclusive, string name)
{
if (value < minInclusive || value > maxInclusive)
throw new ArgumentOutOfRangeException(name, "Expected " + minInclusive + ".." + maxInclusive);
}
}
public class Program
{
static int ScoreFor(string userId, int level)
{
Guard.NotNullOrEmpty(userId, "userId");
Guard.InRange(level, 1, 10, "level");
// pretend logic
return level * 100;
}
public static void Main(string[] args)
{
Console.WriteLine(ScoreFor("u42", 3));
try { Console.WriteLine(ScoreFor(null, 3)); } catch (Exception ex) { Console.WriteLine(ex.GetType().Name); }
}
}
TryParse 验证
对于常规的无效输入,优先使用 TryParse 风格的方法,让其返回 false 而不是抛出异常。
using System;
// Use TryParse for user-provided text; avoid throwing for normal invalid input.
public class Program
{
public static bool TryGetPort(string text, out int port)
{
port = 0;
int value;
if (!int.TryParse(text, out value)) return false;
if (value < 1 || value > 65535) return false;
port = value;
return true;
}
public static void Main(string[] args)
{
int p;
Console.WriteLine("8080 -> " + (TryGetPort("8080", out p) ? ("ok " + p) : "invalid"));
Console.WriteLine("abc -> " + (TryGetPort("abc", out p) ? ("ok " + p) : "invalid"));
}
}
抛出异常还是返回结果
- 对于程序员错误(错误的 API 使用方式、不允许为空的位置出现空值、超出范围),应抛出异常
- 对于正常的用户错误(无效文本),应返回 false/结果
- 使用特定的异常类型;包含参数名称
- 从外到内进行验证:先执行开销低的检查
最佳实践
提示:
- 在边界处验证(控制器、公共 API)
- 优先使用小型保护方法,而不是深层嵌套
- 保持错误消息简短清晰
- 只在边界处记录一次日志,不要在每个保护方法中都记录
保护子句的含义
回顾
回顾:使用保护子句及早验证,对于程序员错误抛出特定异常,并对日常用户输入使用 TryParse。
常见问题解答
「保护与验证模式」课时是免费的吗?
是的 — 「保护与验证模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 3 节课。
「保护与验证模式」这节课中我会学到什么?
使用保护子句及早验证输入,抛出正确的异常,并对用户数据使用 TryParse 风格的检查。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。
「保护与验证模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。