TechInterviewNotes

‹ Library

Learn C#

Save

Updated 29 Jul 2026 · 2 min read

Learn C# with examples and analogy

Download PDFOpen PDF

1. Regex

Normal people write - works but slow at startup:

C#

private static readonly Regex PhoneRegex =    new Regex(@"^\d{10}$", RegexOptions.Compiled);
bool ok = PhoneRegex.IsMatch(input);

We should write - compile time generated:

C#

public partial class Patterns{    [GeneratedRegex(@"^\d{10}$")]    public static partial Regex Phone();}
bool ok = Patterns.Phone().IsMatch(input);

2 lines hidden

Why better: No 50ms compile at startup, 3x faster, works in NativeAOT. Normal version breaks in AOT.

2. JSON Serialization

Normal people write - uses reflection at runtime:

C#

string json = JsonSerializer.Serialize(user);User obj = JsonSerializer.Deserialize<User>(json);

We should write - AOT safe, no reflection:

C#

[JsonSerializable(typeof(User))]public partial class MyJsonContext : JsonSerializerContext {}
string json = JsonSerializer.Serialize(user, MyJsonContext.Default.User);User obj = JsonSerializer.Deserialize(json, MyJsonContext.Default.User);

Why better: 40% faster, zero reflection, no crash when you publish with PublishAot=true. Normal version will throw in AOT.

3. Logging

Normal people write - allocates even when log is off:

C#

logger.LogInformation($"User {userId} logged in at {DateTime.Now}");// This creates a string ALWAYS, even if Information logs are disabled

We should write - zero allocation:

C#

public static partial class Log{    [LoggerMessage(Level = LogLevel.Information, Message = "User {UserId} logged in")]    public static partial void UserLoggedIn(this ILogger logger, int userId);}
logger.UserLoggedIn(userId);// Generates if(IsEnabled) check internally, no string created if off

3 lines hidden

Why better: Microsoft's benchmarks show 10x less allocation under load. Normal version creates GC pressure on every request.

4. Object Mapping

Normal people write - AutoMapper, reflection:

C#

var dto = _mapper.Map<UserDto>(user); // reflection at runtime, slow

We should write - Mapperly generator:

C#

[Mapper]public partial class UserMapper{    public partial UserDto MapToDto(User user);}
var mapper = new UserMapper();var dto = mapper.MapToDto(user); // generates direct assignment: dto.Name = user.Name

3 lines hidden

Why better: No reflection, 10x faster than AutoMapper, AOT safe. You can see the generated dto.Name = user.Name code in Analyzers.

The pattern is always same:
Normal = does work at RUNTIME.
Top 1% = moves work to COMPILE TIME.

Learn C# — TechInterviewNotes