Friday, November 01, 2024

Be A Developer That Uses AI

Developers will not be replaced by AI, they'll be replaced by developers that use AI.

Generative AI tools are revolutionizing the way developers work. According to McKinsey, these tools can significantly speed up common tasks:

  • Documenting Code: Tasks that typically take hours can be completed in half the time.
  • Writing New Code: Developers can write new code nearly twice as fast.
  • Optimizing Existing Code: Code optimization can be done in nearly two-thirds the time it usually takes.
  • A study by Microsoft emphasizes the value of deep work for developers. Devs who have dedicated time for uninterrupted work report feeling 50% more productive.
Improving the overall developer experience has a direct impact on productivity. McKinsey found that a better developer experience can lead to a 20-30% reduction in customer-reported product defects and a 20% improvement in employee experience scores. 


    Wednesday, August 07, 2024

    10 Takeaways for GitHub Copilot

    Having used AI tool GitHub Copilot for a year, I realized that learning GitHub Copilot is like learning any software. The more you use it, the better you will be. Overall, my experience with GitHub Copilot was very positive. GitHub Copilot helped me boost my productivity and happiness of the software development. 

    Here are a few tips to become a better software developer boosted by GitHub Copilot or any Artificial Intelligence tools.

     Tips

    • Open the relevant files.
    • Provide specific comments.
    • Reference code using #file.
    • Generate model class from the database.
    • Generate multiple classes in one prompt.
    • Write the prompt incrementally.
    • Reuse previous prompts. Give specific instructions.
    • Don't start a new session. Previous prompts will be gone.
    • Don't expect AI gives you the same result every time.
    • Double check the result. GitHub Copilot could have bugs.
    • Generate the commit description with GitHub Copilot.
    • Generate the PR description with GitHub Copilot
    • Explain the commit with GitHub Copilot
    • Explain the PR with GitHub Copilot
    • Suggest the fix from GitHub Copilot
    • Fix the unit tests related to the recent changes using GitHub Copilot

     Verdict

    GitHub Copilot is easy to use in Visual Studio. It’s a delight to see Copilot’s suggestions. The time saved for the developers justifies the cost. GitHub Copilot and Jetbrains Resharper are complementary to each other. GitHub Copilot is better than Jetbrains Resharper in code auto-generating. GitHub Copilot can’t replace Jetbrains Resharper in areas such as live templates, code refactoring, and code navigation.

    • Increase developer productivity 
    • Increase developer happiness
    • Accelerate software development
    • Remain in your flow in the beloved editor (VS or VSCode)


    Sunday, August 04, 2024

    C# From-The-End Index Operator ^ C# 13

    Implicit index access

    With C# 13, the implicit “From-The End” index operator ^ can now be used in object initializers. You can use ^ to specify a position in a collection that is relative to the end of the collection.

    For example, consider the following class.

    class InitializerDemo
    {
        public int[] integers { get; set; } = new int[5];
    }

    You can now use the following piece of code in C# 13 to take advantage of the index operator.

    var arr = new InitializerDemo
    {
        integers =
        {
            [0] = 100,
            [^1] = 1000
        }
    };

    When you execute the above program, arr.Integers[0] will have the value 100 while arr.Integers[4] will have the value 1000. 

    C# Partial Properties C# 13

    Partial properties

    Partial properties, like partial methods, are a new feature added in C# 13. They support source generators and are used to separate the declaration of a property from its implementation code. Note that partial methods were introduced earlier and gained some traction in C# 9.

    The following code snippet illustrates how partial properties can be used:

    partial class MyClass
    {
        string myField;
        public partial string MyProperty { get; set; }
        public partial string MyProperty
        { get => myField; set => myField = value; }
    }

    It should be noted that when you declare a partial property with accessors having semicolon bodies without any implementation code inside, it is assumed to be a defining declaration. By contrast, when a partial property has accessors that contain implementation code, it is considered to be an implementing declaration.

    Partial properties are used to provide support for source generators. Their sole purpose is to isolate the declaration of a property from its implementation code.

    C# Using ref and unsafe in async methods and iterators C# 13

     Using ref and unsafe in async methods and iterators

    Before C# 13, declaring local ref variables or local variables of a ref struct type in either async methods or methods that use yield return, commonly known as iterator methods, was not possible. Nor could these methods have an unsafe context. C# 13 allows the declaration of ref local variables and local variables of a ref struct type in asynchronous methods. Similarly, C# 13 allows unsafe contexts in iterator methods.

    You can also safely use types like System.ReadOnlySpan<T> in asynchronous and iterator methods. 

    The primary benefit of using a ref struct is to get the benefit of pointers in a safe context and prevent memory allocation in several common scenarios. Hence, by using ref struct types in async methods and iterators, you can improve the performance of your application. This is the most useful new feature in C# 13 in my opinion.

    C# 13 allows you to make a type argument a ref struct by specifying allows ref struct in the where clause of the type parameter. Note that if you use a type parameter specified with allows ref struct, then you are including all of the behaviors and restrictions of the ref struct type.

    Consider the following piece of code that shows a ref struct and a method that uses it as a parameter.

    ref struct TestStruct
    {

    }

    TestStruct TestMethod<TestStruct>(TestStruct p)
        where TestStruct : allows ref struct
        => p;

    The following code snippet illustrates how ref struct instances can be created and used inside an async method.

    async Task<int> Test()
    {
        TestStruct testStruct = new TestStruct();
        TestMethod(testStruct);
        return await Task.FromResult(0);
    }

    C# New Lock Object C# 13

    New Lock object

    .NET 9 introduces a new thread synchronization type called System.Threading.Lock, which provides enhanced thread synchronization capabilities. Note that the runtime will detect whether the target of a lock is a Lock object, in which case it will use the updated API in lieu of the traditional API that uses System.Threading.Monitor. The compiler also will recognize if you convert a Lock object to some other type where System.Threading.Monitor code would be generated.

    Let’s compare the old and new APIs. The code snippet below implements synchronization using the traditional API.

    public class DbManager
    {
        private object objLock = new object();
        public void InsertData()
        {
            lock (objLock)
            {
                //Your usual code to insert data to the database
            }
        }
    }

    To use the new API, you need to change only one line of code:

    private System.Threading.Lock objLock = new System.Threading.Lock();

    Hence, the updated DbManager class would have the following code.

    public class DbManager
    {
        private System.Threading.Lock objLock = new System.Threading.Lock();
        public void InsertData()
        {
            lock (objLock)
            {
                //Your usual code to insert data to the database
            }
        }

    } 

    Monday, July 29, 2024

    C# Extension Types in C# 14

    Since C# 3, extension methods have allowed you to add methods to an underlying type, even if you cannot change its code. LINQ is an example of a set of extension methods on IEnumerable<T>. The LINQ extension methods appear as if they were instance methods on the underlying type.

    Proposed C# 14 takes the next step with extension types. This is a new kind of type that supplies extension members for an underlying type. They have methods, properties and other members that can be instance or static. Instance extension types cannot hold state. For example, they can’t include fields. They can access state on the underlying type or in another location.

    There are two kinds of extension types: implicit and explicit extensions. Implicit extension types apply to all occurrences of the underlying type – in the same way extension methods do today. Explicit extension methods and properties apply only to instances of the underlying type that have been converted to the explicit extension type.

    An extension type builds on an underlying type, which are just normal C# types. One of the reasons you might use an extension is that you can’t change the code of the underlying type.

    Let’s look at some examples, starting with the underlying types and assuming we don’t have access to change their code:

    public class Person()
    {
        public required string GivenName { get; init; } 
        public required string SurName { get; init; }
        public required Organization Organization { get; init; } 
    } 
    
    public class Organization()
    {
        public required string Name { get; init; }
        public required List<Team> Teams { get; init; }
    } 
    
    public class Team()
    {
        public required string TeamName { get; init; }
        public required Person Lead { get; init; }
        public required IEnumerable<Person> Members { get; init; }
    } 

    A bit of LINQ code can return whether a Person is a lead. Since we don’t want to write this piece of code every time it’s needed, we could write an extension method, and if desired control access to it via namespaces. Or, we could use and implicit extension type to organize the extensions for the Person class, and provide IsLead as a property to all Person instances:

    public implicit extension PersonExtension for Person
    {
        public bool IsLead
            => this.Organization
                .Teams
                .Any(team => team.Lead == this);
    }

    This property would be called as:

    if (person.IsLead) { ... }

    Explicit extensions let you give extra features to specific instances of a type. For example, it makes sense to retrieve which teams a person leads. An explicit extension can provide the Teams property only to leads:

    public explicit extension Lead for Person
    {
        public IEnumerable<Team> Teams 
            => this.Organization
                .Teams
                .Where(team => team.Lead == this);
    }

    Both implicit and explicit extension types support static members as well as instance members. One way to use this is to provide defaults specific to your scenario. In this case, we have only one organization, and it’s quite awkward to specify it every time we create a person:

    public implicit extension OrganizationExtension for Organization
    {
       private static Organization ourOrganization = new Organization("C# Design");
    
       public static Person CreatePerson(string givenName, string surName) 
           => new(givenName, surName, ourOrganization);
    }

    Putting this together:

    var mads = Organization.CreatePerson("Mads", "Torgersen");
    // code to add more people and teams
    if (mads.IsLead)
    {
        Lead madsAsLead = mads;
        PrintReport(madsAsLead.Teams);
    }

    From a usage perspective, extension types allow you to simplify the code that provides the important work and logic of your application. It does this by organizing extensions and supplying extensions that customize specific instances of the underlying objects. From a technical perspective, extension types are an enhancement to the extension methods you use today. Learn more on Extension Types in Mads Torgersen and Dustin Campbell’s What’s new in C# talk


    Be A Developer That Uses AI

    Developers will not be replaced by AI, they'll be replaced by developers that use AI. Generative AI tools are revolutionizing the way de...