𝗦𝗧𝗢𝗣 𝗪𝗥𝗜𝗧𝗜𝗡𝗚 𝟮𝟬-𝗣𝗔𝗥𝗔𝗠𝗘𝗧𝗘𝗥 𝗖𝗢𝗡𝗦𝗧𝗥𝗨𝗖𝗧𝗢𝗥𝗦. 🛑 If you’re still building massive constructors just to ensure your objects aren't "hollow" or invalid, you’re stuck in a boilerplate nightmare. It's time to move to modern C#. Let’s talk about a feature that finally fixed the "Incomplete Object" problem: 𝗿𝗲𝗾𝘂𝗶𝗿𝗲𝗱 members. 𝗧𝗛𝗘 𝗣𝗥𝗢𝗕𝗟𝗘𝗠: 𝗧𝗛𝗘 𝗖𝗢𝗡𝗦𝗧𝗥𝗨𝗖𝗧𝗢𝗥 𝗧𝗥𝗔𝗣 In the old days, you had two bad choices: Constructors: Great for safety, but they become a mess of parameters that are hard to read and maintain. Object Initializers: Look beautiful (new User { Name = "K" }), but they don't force the developer to set anything. You end up with NullReferenceExceptions because someone forgot a field. You were choosing between safety and syntax. 𝗧𝗛𝗘 𝗦𝗢𝗟𝗨𝗧𝗜𝗢𝗡: 𝗧𝗛𝗘 𝗿𝗲𝗾𝘂𝗶𝗿𝗲𝗱 𝗞𝗘𝗬𝗪𝗢𝗥𝗗 Introduced in C# 11, the required modifier gives you the best of both worlds. You get the clean look of object initializers with the "iron-clad" safety of a constructor. 𝗧𝗛𝗘 𝗖𝗢𝗗𝗘: public class User { // The compiler will THROW an error if this isn't set during initialization public required string Email { get; init; } public required string Username { get; init; } public DateTime JoinedDate { get; init; } = DateTime.UtcNow; } // ✅ This works perfectly var user1 = new User { Email = "hello@example.com", Username = "DevGuru" }; // ❌ This won't even COMPILE var user2 = new User { Email = "missing_username@example.com" }; 𝗪𝗛𝗬 𝗧𝗛𝗜𝗦 𝗜𝗦 𝗔 𝗪𝗜𝗡: Compile-Time Safety: If a dev adds a new "required" property to a class, every piece of code that creates that object will break immediately—preventing runtime bugs before they happen. Zero Boilerplate: No more mapping 15 parameters from a constructor to private fields. Readability: Object initializers are much easier to scan than a long list of constructor arguments where you can't tell which string is "FirstName" and which is "LastName." 𝗧𝗛𝗜𝗡𝗞𝗜𝗡𝗚 𝗢𝗨𝗧𝗦𝗜𝗗𝗘 𝗧𝗛𝗘 𝗕𝗢𝗫 📦 Combine required with init properties. This creates Immutable, Mandatory Data Structures. You ensure the data is there when created, and you guarantee it can't be changed accidentally later. It’s the ultimate "defensive programming" move. 𝗧𝗛𝗘 𝗧𝗔𝗞𝗘𝗔𝗪𝗔𝗬: Stop doing the manual labor of checking for nulls or writing endless constructor overloads. Use required to let the compiler be your bodyguard. #CSharp #DotNet #CleanCode #ProgrammingTips #SoftwareArchitecture #CodingLife #Innovation
C# 11 Required Modifier for Immutable Data Structures
More Relevant Posts
-
𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝘆 𝗜𝗻𝗷𝗲𝗰𝘁𝗶𝗼𝗻: 𝗦𝘁𝗼𝗽 𝗡𝗲𝘄-𝗶𝗻𝗴 𝗨𝗽 𝗬𝗼𝘂𝗿 𝗣𝗿𝗼𝗯𝗹𝗲𝗺𝘀 If you’re seeing new Service() inside your classes, you’re looking at a maintenance nightmare. Much like the Builder Pattern solves "𝗖𝗼𝗻𝘀𝘁𝗿𝘂𝗰𝘁𝗼𝗿 𝗖𝗵𝗮𝗼𝘀", 𝗗𝗲𝗽𝗲𝗻𝗱𝗲𝗻𝗰𝘆 𝗜𝗻𝗷𝗲𝗰𝘁𝗶𝗼𝗻 (𝗗𝗜) solves "𝗖𝗼𝘂𝗽𝗹𝗶𝗻𝗴 𝗖𝗵𝗮𝗼𝘀" 𝗧𝗵𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺: 𝗥𝗶𝗴𝗶𝗱 𝗖𝗼𝗱𝗲 Hardcoding dependencies inside a class creates 𝗧𝗶𝗴𝗵𝘁 𝗖𝗼𝘂𝗽𝗹𝗶𝗻𝗴. If your class creates its own 𝘚𝘲𝘭𝘙𝘦𝘱𝘰𝘴𝘪𝘵𝘰𝘳𝘺, you can’t swap it for a 𝘔𝘰𝘤𝘬𝘙𝘦𝘱𝘰𝘴𝘪𝘵𝘰𝘳𝘺 during testing or a 𝘔𝘰𝘯𝘨𝘰𝘙𝘦𝘱𝘰𝘴𝘪𝘵𝘰𝘳𝘺 later without rewriting the class itself. It's rigid, fragile, and untestable. 𝗧𝗵𝗲 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻: "𝗔𝘀𝗸, 𝗗𝗼𝗻’𝘁 𝗕𝘂𝗶𝗹𝗱" 𝗗𝗜 implements 𝗜𝗻𝘃𝗲𝗿𝘀𝗶𝗼𝗻 𝗼𝗳 𝗖𝗼𝗻𝘁𝗿𝗼𝗹 (𝗜𝗼𝗖). Instead of a class 𝗯𝘂𝗶𝗹𝗱𝗶𝗻𝗴 its own tools, it simply 𝗮𝘀𝗸𝘀 for them via its constructor. Interfaces: Define the "𝘤𝘰𝘯𝘵𝘳𝘢𝘤𝘵" (what the tool does). Implementation: The "𝘤𝘰𝘯𝘤𝘳𝘦𝘵𝘦" class (how the tool does it). The Container: The "𝘱𝘩𝘰𝘯𝘦𝘣𝘰𝘰𝘬" that matches the interface to the implementation. 𝗗𝗜 𝗶𝗻 𝘁𝗵𝗲 .𝗡𝗘𝗧 𝗪𝗼𝗿𝗹𝗱 In .NET Core/8/9, this is handled natively in 𝗣𝗿𝗼𝗴𝗿𝗮𝗺.𝗰𝘀: 𝙗𝙪𝙞𝙡𝙙𝙚𝙧.𝙎𝙚𝙧𝙫𝙞𝙘𝙚𝙨.𝘼𝙙𝙙𝙎𝙘𝙤𝙥𝙚𝙙<𝙄𝙋𝙧𝙤𝙙𝙪𝙘𝙩𝙎𝙚𝙧𝙫𝙞𝙘𝙚, 𝙋𝙧𝙤𝙙𝙪𝙘𝙩𝙎𝙚𝙧𝙫𝙞𝙘𝙚>(); The framework automatically injects the correct instance whenever IProductService is requested in a constructor. 𝗪𝗵𝘆 𝗜𝘁’𝘀 𝗮 𝗕𝗮𝗰𝗸𝗲𝗻𝗱 𝗣𝗼𝘄𝗲𝗿 𝗠𝗼𝘃𝗲 • Unit Testing: Easily inject "Mock" services to test logic without hitting a real database. • Lifetime Management: Control whether an object is created once (Singleton), per request (Scoped), or every time (Transient). • Maintainability: Change your entire data access layer in one line of code within Program.cs. 𝗧𝗵𝗲 𝗕𝗼𝘁𝘁𝗼𝗺 𝗟𝗶𝗻𝗲 Don't let your classes be "control freaks." If a class needs a tool, don't make it build that tool—inject it. Keep your architecture flexible and your code clean. #CSharp #DotNet #CleanCode #DependencyInjection #SoftwareArchitecture #Backend #DEPI
To view or add a comment, sign in
-
🚀 C# 15 Just Changed How We Handle Multiple Types! The wait is finally over. Microsoft just dropped Union Types in .NET 11 Preview 2, and this is one of the most-requested C# features we've ever seen. What are Union Types? Think about this: You have a value that could be a string, int, or DateTime. Before, you had to: - Use object and cast manually - Return tuples with IsValid flags - Create wrapper classes - Hope the runtime doesn't surprise you Now you can simply write: ValueWithUnion<string | int | DateTime> value = GetData(); And let the compiler ensure you handle all cases. No casting. No runtime surprises. Why This Matters ✅ Compile-time exhaustiveness - Missing a case? That's a compile error. ✅ Zero-cost performance - Stored just like regular types. ✅ Self-documenting code - The type signature tells the story. ✅ Type-safe patterns - No more object casting nightmares. Real-World Example: Before: object result = GetValue(); if (result is string str) { ... } else if (result is int num) { ... } Now: var result = GetValue(); // returns string | int switch (result) { case string str: ... case int num: ... } Simple. Clean. Correct. Practical Use Cases: 📌 API response handling (success/error/redirect) 📌 Validation results (error code, message, or detailed errors) 📌 Cache values that could be any type 📌 Command patterns with multiple failure modes Try It Today: Union Types are in .NET 11 Preview 2. Get the SDK here: https://lnkd.in/eseijNqc Requires Visual Studio 2026 Insider or later. What Do You Think? I've been testing this for a few weeks and it's already changed how I write code. Type handling feels... natural again. What's been your biggest pain point with type handling in C#? Drop your thoughts below! 👇 💬 Have questions about the implementation? Ask me in the comments. Read the full article: https://lnkd.in/eKv2Naju Connect on LinkedIn: https://lnkd.in/eAHKnx84 Portfolio: https://lnkd.in/ekRNczNQ #DOTNET #CSharp #Programming #SoftwareDevelopment #TechInnovations #Coding #DevCommunity #CSharp15 #DotNet11 #CleanCode
To view or add a comment, sign in
-
🚨 Your C# architecture is either your greatest asset or your worst technical debt. There is no in-between. We’ve all been there: you inherit a project, and adding a single new feature feels like defusing a bomb. Everything is tightly coupled, and making one small change breaks three other things. The culprit is almost always poor architecture. When building scalable and maintainable C# applications, setting up the right foundation is crucial. Here are the core principles I rely on to keep codebases clean, testable, and future-proof: 👑 Domain is King: Keep your business logic strictly isolated. Your core domain shouldn't care if you're using Entity Framework, Dapper, SQL Server, or a flat file. 💉 Dependency Injection is Non-Negotiable: Don't tightly couple your components. By relying on abstractions (Interfaces) rather than concrete implementations, you make your code infinitely more modular and testable. 🧅 Embrace Clean Architecture: Separate your concerns into distinct layers (Domain, Application, Infrastructure, Presentation). Rule of thumb: Dependencies must always point inwards toward the Domain! 🧱 Respect SOLID Principles: They aren't just buzzwords for technical interviews; they are the actual foundation of scalable object-oriented design in .NET. Good architecture isn’t about over-engineering a simple CRUD app. It’s about predicting that your app will grow, and protecting your team's sanity when it does. What is your go-to architectural approach for new .NET/C# projects? Do you prefer Clean Architecture, Vertical Slice Architecture, or something else? Let's debate in the comments! 👇 #CSharp #DotNet #SoftwareArchitecture #CleanArchitecture #SoftwareEngineering #DeveloperCommunity #TechLead #Coding
To view or add a comment, sign in
-
GraphCompose v1.4 is live. https://lnkd.in/eyJ2DK5b The last time I properly posted about GraphCompose here, it was v1.1.0. Since then, I did what every developer promises not to do: “I’ll just improve a few things.” A few things later, GraphCompose is no longer just a Java PDF generation project. It has moved much closer to a declarative document layout engine. The idea is simple: Instead of manually fighting PDF coordinates, margins, page breaks, and layout edge cases, you describe the document structure: sections, modules, paragraphs, tables, rows, layers, themes. GraphCompose handles layout, pagination, snapshots, and PDFBox rendering behind the scenes. The new v1.4 line adds: table column spans layer stacks for overlay-style layouts page and section backgrounds fluent rich text DSL reusable BusinessTheme design tokens visual regression scaffolding for generated PDFs stronger documentation and release guardrails Basically, I wanted PDF documents to feel less like drawing on a cave wall with coordinates and more like building UI layouts with components. Still Java. Still PDFBox underneath. But now with a much stronger layout engine on top. This release is a big step for the project: from “generate a PDF” toward “compose a designed document.” Repo: GraphCompose by DemchaAV hashtag #Java #OpenSource #PDFGeneration #SoftwareEngineering #BackendDevelopment #JavaDeveloper #PDFBox
To view or add a comment, sign in
-
-
🚀 𝗠𝗢𝗗𝗘𝗥𝗡 𝗖++ 𝗙𝗘𝗔𝗧𝗨𝗥𝗘: std::as_const (C++17) ✨ 𝗘𝗻𝗳𝗼𝗿𝗰𝗲 𝗖𝗼𝗻𝘀𝘁-𝗖𝗼𝗿𝗿𝗲𝗰𝘁𝗻𝗲𝘀𝘀 𝗪𝗶𝘁𝗵 𝗖𝗹𝗮𝗿𝗶𝘁𝘆 🤔 Ever wanted to treat an object as read-only without copying it? ❌ Creating const copies 🧱 ❌ Risk of accidental modification 😬 ❌ Verbose casting 😵 👉 Code worked… but safety & intent were unclear 💡 𝗘𝗡𝗧𝗘𝗥: std::as_const ✨ A simple utility to get a const reference ✔️ Prevents accidental modification 🔒 ✔️ Zero overhead (no copy!) ⚡ ✔️ Makes intent crystal clear 👀 🧪 Example: #include <iostream> #include <utility> void print(const std::string& str) { std::cout << str << "\n"; } int main() { std::string name = "Abhishek"; print(std::as_const(name)); // treated as const } 👉 💡 𝗞𝗲𝘆 𝗜𝗱𝗲𝗮: “View mutable data as const, safely & clearly” ⚡ 𝗪𝗛𝗬 𝗜𝗧’𝗦 𝗣𝗢𝗪𝗘𝗥𝗙𝗨𝗟 ✔️ 🛡️ Safe → Prevents unintended mutations ✔️ 🧹 Clean → No manual const casting ✔️ ⚡ Efficient → No extra copies ✔️ 🎯 Intentional → Express read-only usage clearly 🧠 𝗞𝗘𝗬 𝗜𝗡𝗦𝗜𝗚𝗛𝗧 Before 😕 👉 const_cast<const T&>(obj) After 😎 👉 std::as_const(obj) ⚠️ 𝗨𝗦𝗘 𝗪𝗜𝗦𝗘𝗟𝗬 ❗ Doesn’t make a copy → original object still mutable elsewhere ❗ Only works with lvalues (no rvalues) ❗ Not a replacement for proper const design 🌍 𝗥𝗘𝗔𝗟-𝗪𝗢𝗥𝗟𝗗 𝗨𝗦𝗘𝗦 🔹 API design enforcing read-only access 🔹 Safer function calls 🔹 Avoiding accidental state changes 🔹 Cleaner generic programming 🏆 𝗧𝗔𝗞𝗘𝗔𝗪𝗔𝗬 👉 std::as_const = 𝗦𝗔𝗙𝗘 + 𝗖𝗟𝗘𝗔𝗥 + 𝗭𝗘𝗥𝗢-𝗖𝗢𝗦𝗧 𝗖𝗢𝗡𝗦𝗧𝗡𝗘𝗦𝗦 ✨ 🚀 Modern C++ isn’t just about performance… 👉 It’s about 𝗦𝗔𝗙𝗘𝗧𝗬 & 𝗜𝗡𝗧𝗘𝗡𝗧 #CPP #ModernCPP #CPP17 #SoftwareEngineering #CleanCode #Programming — 𝗔𝗕𝗛𝗜𝗦𝗛𝗘𝗞 𝗦𝗜𝗡𝗛𝗔
To view or add a comment, sign in
-
-
5 Design Patterns Every Developer Should Master Most bugs aren't caused by bad logic — they're caused by bad structure. Design Patterns are battle-tested solutions to problems you'll encounter in every real-world project. Here are 5 Pattern I reach for all the time: 1. Singleton — "One instance to rule them all." Ensures only ONE instance of a class exists across the app. Use for: Logging, Configuration, DB connections. Watch out: Hidden global state can lead to testing challenges. 2. Factory — "Don't 'new' it, create it." Delegates object creation to a dedicated class. Use for: Creating payment gateways, notification channels, shape objects. This keeps your code open for extension and closed for modification. 3. Strategy — "Swap behavior at runtime." Defines a family of algorithms and makes them interchangeable. Use for: Sorting, Pricing rules, Tax calculations, Auth strategies. This replaces long if/else and switch-case chains with clean polymorphism. 4. Observer — "When X happens, tell everyone." One-to-many dependency — when the subject changes, all observers react. Use for: Event-driven systems, Notifications, MVVM binding. This is built right into C# via event and IObservable<T>. 5. Repository — "Hide the data, expose the intent." Abstracts data access so your business logic doesn't depend on EF, Dapper, or raw SQL. Use for: Clean architecture, Unit testing, Swappable data sources. This pairs beautifully with Dependency Injection. Why this matters: - Fewer bugs - Easier to test - Easier to extend - Easier for new developers to onboard Clean code isn't about being clever. It's about being kind to the next developer — which, 9 times out of 10, is future you. Which design pattern saved your project recently ? #CSharp #DotNet #SoftwareEngineering #DesignPatterns #CleanCode #Programming #Developer #BackendDevelopment #SoftwareArchitecture #CodingTips
To view or add a comment, sign in
-
-
🚀 C# 10.0 (2021) – Less Boilerplate, More Productivity Released with .NET 6, C# 10.0 focused on making your code cleaner, simpler, and more efficient—with small changes that deliver big impact. Here’s a complete breakdown of all key features 👇 ✨ 1. Global Using Directives Declare "using" statements once for the entire project. → No more repeating imports in every file. ✨ 2. File-Scoped Namespaces Write namespaces in a single line. → Reduces indentation and improves readability. ✨ 3. Record Structs Combine value types with record features (immutability + value equality). ✨ 4. Improved Record Types Records now support inheritance and more flexibility. ✨ 5. Const Interpolated Strings Use string interpolation in "const" declarations. ✨ 6. Extended Property Patterns More powerful pattern matching with nested properties. ✨ 7. Lambda Improvements Better type inference + ability to add attributes to lambdas. ✨ 8. "var" in More Places Use "var" in lambda parameters and other scenarios. ✨ 9. Better Nullability Analysis Improved compile-time checks for safer null handling. ✨ 10. Parameterless Struct Constructors Initialize structs with default constructors. ✨ Other Notable Improvements • Implicit global usings in .NET 6 • Performance improvements (JIT & runtime) • Better diagnostics and error messages • Improved async and compiler behavior 💡 Why C# 10.0 Matters? ✔ Reduces repetitive code (global usings) ✔ Improves readability (file-scoped namespaces) ✔ Enhances performance and safety ✔ Makes modern C# even more developer-friendly 📌 Small features, but huge productivity gains for real-world projects. 👉 Which feature made your coding easier? #CSharp #DotNet #CSharp10 #Programming #Developers #Coding #SoftwareEngineering #Tech #LearnToCode #VisualStudio
To view or add a comment, sign in
-
-
C#/.NET Performance Tip — String Concatenation in Loops Many .NET developers still use += inside loops without realizing how expensive it really is. Using result += "x" inside a 1,000-iteration loop is 100 times slower than using StringBuilder.Append. When += is used on a string, .NET must: - Allocate a brand new string on every single iteration - Copy all existing characters into the new buffer - Discard the old string for the garbage collector In contrast, when StringBuilder is used, .NET: - Maintains one internal, growable buffer - Appends characters in place with zero extra allocations - Converts to a string only once at the end This pattern applies anywhere you build text dynamically: - Logging and reporting - CSV / JSON generation - Query construction - Any loop-based text assembly A small change can lead to a massive impact at scale. Benchmark results show: 4.21 us (StringBuilder) vs 412.50 us (+=), with 2.1 KB vs 2,500 KB allocated. Pre-size your StringBuilder when you know the capacity — even better. #csharp #dotnet #performance #programming #tips #coding #softwaredevelopment #aspnetcore #developer #cleancode
To view or add a comment, sign in
-
-
💡 Primary Constructors in C#: Simplifying Class Design Introduced with C# 12 (2023), primary constructors change the way we write and structure our classes — making code more concise and expressive. 📅 The concept Primary constructors allow you to define constructor parameters directly in the class declaration, instead of writing a separate constructor. 🧩 Before (classic approach) public class OrderService { private readonly IOrderRepository _orderRepository; private readonly IEmailSender _emailSender; public OrderService(IOrderRepository orderRepository, IEmailSender emailSender) { _orderRepository = orderRepository; _emailSender = emailSender; } public async Task PlaceOrderAsync(Order order) { await _orderRepository.AddAsync(order); await _emailSender.SendOrderConfirmationAsync(order.CustomerEmail); } } ⚡ After (primary constructor) public class OrderService( IOrderRepository orderRepository, IEmailSender emailSender) { public async Task PlaceOrderAsync(Order order) { await orderRepository.AddAsync(order); await emailSender.SendOrderConfirmationAsync(order.CustomerEmail); } } 👉 Same behavior, less boilerplate, clearer intent Advantages ✔️ Less boilerplate → No repeated constructor + assignment ✔️ Better readability → Dependencies are visible in the class signature ✔️ Great for Dependency Injection → Perfect for ASP.NET Core services and microservices ✔️ Consistency with modern C# (records, minimal APIs) Trade-offs ❌ New syntax to learn ❌ Can hurt readability with too many parameters ❌ Less suitable for complex constructor logic ❌ Not ideal when multiple constructors are needed When to use ✔️ Simple services ✔️ DTOs / lightweight classes ✔️ 1–5 dependencies max ✔️ Clean architecture with DI When to avoid ❌ Complex initialization logic ❌ Too many dependencies ❌ Multiple construction flows Conclusion Primary constructors don’t replace classic constructors—they refine how we write simple, dependency-driven classes. 👉 Less noise 👉 More clarity 👉 More modern C# #CSharp #DotNet #Programming #SoftwareEngineering #CleanCode #ASPNetCore #SvetlanaVrabie
To view or add a comment, sign in
-
-
Why do we use public static void Main(){} in C# ? static (The Most Critical Keyword):: This is the one that usually trips people up. In C#, you usually need to create an "instance" (an object) of a class to use its methods. The Catch: If Main were not static, the CLR would have to create an object of your class first. But to create an object, it needs to run code... and it can't run code until it finds Main. The Solution: By making it static, the method belongs to the class itself, not an object. The CLR can just call Program.Main() directly as soon as the app starts. public (The Gateway):: While modern C# (and certain compilers) allows private or internal entry points, public is the standard. Why: It tells the CLR, "This method is visible and accessible from outside this specific file/assembly." It ensures the execution engine has "permission" to walk through the front door of your code. void (The Result):: The Meaning: It tells the operating system, "I’m going to do my job and then just stop." The Alternative: Sometimes you’ll see static int Main(). In that case, the program returns a number (an Exit Code) to the OS. (e.g., return 0; means success, return 1; means an error occurred). Main (The Identifier):: The Rule: C# is case-sensitive. It must be capitalized Main. If you name it main, the compiler will look right past it and tell you that your program is missing an entry point.
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development