| name | enforcing-generated-regex |
| description | Force Regex to use GeneratedRegex Source Generator attribute instead of runtime Regex construction for compile-time optimization. |
GeneratedRegex Source Generator ๊ฐ์
์ค๋ช
Regex๋ฅผ ๋ฐํ์์ new Regex(...) ๋๋ Regex.IsMatch(pattern) ํํ๋ก ์์ฑํ๋ฉด ๋งค๋ฒ ์ ๊ท์์ ํด์ํ๊ณ ์ปดํ์ผํด์ผ ํฉ๋๋ค.
[GeneratedRegex] ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ฌ์ฉํ๋ฉด Source Generator๊ฐ ์ปดํ์ผ ํ์์ ์ ๊ท์์ ์ต์ ํ๋ ์ฝ๋๋ก ๋ณํํ์ฌ ์ฑ๋ฅ๊ณผ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ด ํฌ๊ฒ ํฅ์๋ฉ๋๋ค.
๊ท์น
new Regex(pattern, RegexOptions.Compiled) ๋์ [GeneratedRegex(pattern)] ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค
[GeneratedRegex]๋ฅผ ์ฌ์ฉํ๋ ํด๋์ค๋ ๋ฐ๋์ partial๋ก ์ ์ธํฉ๋๋ค
- ๋ฉ์๋ ์๊ทธ๋์ฒ๋
private static partial Regex MethodName(); ํํ์
๋๋ค
- ํธ์ถ ์
MethodName() (๋ฉ์๋ ํธ์ถ)์ผ๋ก ์ฌ์ฉํฉ๋๋ค
RegexOptions๊ฐ ํ์ํ๋ฉด ์ดํธ๋ฆฌ๋ทฐํธ ๋ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌํฉ๋๋ค
Worst Case (๋์ ์)
public sealed class Validator
{
private static readonly Regex EmailPattern = new(@"^[\w.+-]+@[\w-]+\.[\w.]+$", RegexOptions.Compiled);
private static readonly Regex PhonePattern = new(@"^\d{2,3}-\d{3,4}-\d{4}$", RegexOptions.Compiled);
public bool IsValidEmail(string email) => EmailPattern.IsMatch(email);
public bool IsValidPhone(string phone) => PhonePattern.IsMatch(phone);
}
Best Case (์ข์ ์)
public sealed partial class Validator
{
[GeneratedRegex(@"^[\w.+-]+@[\w-]+\.[\w.]+$")]
private static partial Regex EmailPattern();
[GeneratedRegex(@"^\d{2,3}-\d{3,4}-\d{4}$")]
private static partial Regex PhonePattern();
public bool IsValidEmail(string email) => EmailPattern().IsMatch(email);
public bool IsValidPhone(string phone) => PhonePattern().IsMatch(phone);
}
RegexOptions๊ฐ ํ์ํ ๊ฒฝ์ฐ
private static readonly Regex NamePattern = new(@"^[a-z]+$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
[GeneratedRegex(@"^[a-z]+$", RegexOptions.IgnoreCase)]
private static partial Regex NamePattern();
์ ์ฉ ๋์
- ๋ชจ๋
new Regex(...) ์ธ์คํด์ค ์์ฑ
- ๋ชจ๋
static readonly Regex ํ๋
Regex.IsMatch(input, pattern) ์ ์ ํธ์ถ (๋ฐ๋ณต ์ฌ์ฉ ์)
- ํ
์คํธ ์ฝ๋์ ์ ๊ท์ ํจํด (๋ฐ๋ณต ์คํ๋๋ ๊ฒฝ์ฐ)