介紹

學習如何成為更好的開發人員需要不斷提升自己的技能。一個人如何學習成長並成為更好的開發人員?讓我們探討幾個總體上適用於大多數開發人員的想法。程式碼範例全部採用 C# 語言,之所以選擇它們是因為它們對於大多數開發人員來說並不常見,並且是在內部完成的。

腳步

  • Pluralsight是一個付費網站,提供數百門 C# 課程。首先使用他們的人工智慧評估,這將引導您走上正確的道路。許多課程也有自己的評估。 Pluralsight 讓您輕鬆地向高評價作者學習,並透過任何裝置(例如筆記型電腦、手機或平板電腦)存取課程。 Pluralsite 提供免費試用,有時還會在購買訂閱時提供折扣。

  • 使用微軟學習。無論您是剛開始職業生涯,還是經驗豐富的專業人士,我們的自我導向方法都可以幫助您更快、更有信心地按照自己的步調實現目標。透過互動式模組和路徑培養技能或向講師學習。以您的方式學習和成長。

  • 花時間閱讀 Microsoft 文件,例如,閱讀C# 程式的一般結構、類型運算子和表達式語句、各種類別、物件導向程式設計等等。

  • 在學習過程中,嘗試使用控制台或單元測試專案使事情變得簡單,換句話說,將後端學習與前端使用者介面學習分開。

  • 在您感覺舒服的某個時間點,確定一個簡單的專案,在編碼之前寫出任務,然後編寫程式碼,而不是同時思考和編碼。新手等級的思考和編碼簡直就是一場即將發生的災難。

  • 在網路上尋找資訊並找到解決方案時,不要簡單地複製和貼上,檢查程式碼,在使用所述程式碼之前先嘗試弄清楚它在做什麼。

  • 了解如何在 Visual Studio 中使用 GitHub 來備份和版本程式碼。假設您編寫了程式碼並破壞了它,透過 GitHub 儲存庫中的正確版本控制,您可以還原變更並還原程式碼。

  • 使用 .NET Framework Core 6 或 .NET Core Framework 8 而不是 .NET Framework classic,因為使用 .NET Core 有更多好處

  • 如果學習使用資料,請從 SQL-Server Express 開始並安裝 SSMS (SQL-Server Management Studio),同時學習使用 Entity Framework Core。

  • 充分了解學習任何語言時慢速學習比快速學習好,而且沒有人知道這一切。

了解如何使用除錯器

加速學習的工具

Microsoft Visual Studio 絕對是最好的 IDE(整合開發環境),它具有以下專案可以增加學習並節省編碼時間。

  • 適用於 Visual Studio 和 SSMS 的 Red Gate SQL 提示符

  • 高級 IntelliSense 風格的程式碼完成

  • 重構 SQL 程式碼

  • SSMS SQL 歷史記錄

  • 以及更多

  • Jetbrains ReSharper這是一個非常寶貴的 Visual Studio 擴充功能。

  • EF Power Tools可輕鬆對 EF Core 的 SQL-Server 資料庫進行逆向工程

深入了解程式碼基礎知識

掌握基礎知識後,尋找有助於成長為更好的開發人員的程式碼範例。

一個可能的途徑是使用Microsoft Entity Framework Core (EF Core) 或使用Dapper等資料提供者來處理資料庫。

還有其他處理資料的方法,但 EF Core 和 Dapper 在效能和易於學習方面是最好的。

在 Web 上尋找程式碼範例時,請確保它們適用於您的專案的 .NET Framework,因為 .NET Framework 4.8 程式碼範例與 .NET Core 8 Framework 有很大不同。

Microsoft 每年都會為 EF Core 建立程式碼範例,但在許多情況下,其結構可能不適合缺乏經驗的開發人員學習,因此 Karen Payne 採用 EF Core 8 程式碼範例並建立了以下文章/儲存庫,在大多數情況下,這些文章/儲存庫很容易學習。

第 1 課 - SQL-Server 計算列

EF 核心版本

{% cta https://github.com/karenpayneoregon/sql-basics/tree/master/EF\_CoreBirthdaysCompulatedColumns %} 範例專案 {% endcta %}

計算列是虛擬列,除非該列被標記為 PERSISTED,否則不會實際儲存在表中。計算列表達式可以使用其他欄位中的資料來計算其所屬列的值。您可以使用 SQL Server Management Studio (SSMS) 或 Transact-SQL (T-SQL) 為 SQL Server 中的計算列指定運算式。

完整文章,請參閱SQL-Server:使用 Ef Core 計算列

但在這裡,我們將使用 EF Core 和 Dapper 從開始和演練使用情況建立一個計算列。

原文來自以下 Stackoverflow貼。取得出生日期和目前日期,用出生日期減去目前日期,然後除以 10,000。

在 SSMS(SQL Server Management Studio)中

請注意,在程式碼範例中,完整資料庫存在於腳本資料夾下的專案 EF_CoreBirthdaysCompulatedColumns 中。在執行腳本之前,請在 SSMS 中建立資料庫,然後執行腳本來建立表格並填入資料。

另請注意,在程式碼範例中,連接字串使用 NuGet 套件ConsoleConfigurationLibrary駐留在 appsettings.json 中。

表結構

表結構

SQL

選擇語句

將聲明分開。

  • 使用日期分隔符號格式化兩個日期並將每個日期轉換為整數。

  • 從目前日期減去出生日期,括號很重要。

  • 將以上除以 10,000 即可得到年齡。

結果

SELECT 的結果

現在為名為 YearsOld 的表建立一個 nvarchar 類型的新欄位,並將此語句放入計算列屬性中,然後儲存變更。

(CAST(FORMAT(GETDATE(), 'yyyyMMdd') AS INTEGER) - CAST(FORMAT(BirthDate, 'yyyyMMdd') AS INTEGER)) / 10000

ssms中的表設計

使用 EF Power Tools 後,將產生以下類別。

代表 SQL-Server 資料庫表的模型。

public partial class BirthDays
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateOnly? BirthDate { get; set; }

    public int? YearsOld { get; set; }
}

所謂的DbContext和與資料庫互動的配置。

注意 YearsOld 上的HasCompulatedColumnSql ,這是我們的計算列。

public partial class Context : DbContext
{
    public Context()
    {
    }

    public Context(DbContextOptions<Context> options)
        : base(options)
    {
    }

    public virtual DbSet<BirthDays> BirthDays { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
        => optionsBuilder.UseSqlServer(DataConnections.Instance.MainConnection);

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BirthDays>(entity =>
        {
            entity.Property(e => e.YearsOld).HasComputedColumnSql("((CONVERT([int],format(getdate(),'yyyyMMdd'))-CONVERT([int],format([BirthDate],'yyyyMMdd')))/(10000))", false);
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

筆記

執行上述工作有兩個陣營:資料庫優先或程式碼優先。對於剛開始使用 EF Core 的人來說,資料庫優先是最好的路徑。

要查看資料, Spectre.Console用於建立一個漂亮的表格。

internal partial class Program
{
    static async Task Main(string[] args)
    {
        await Setup();
        var table = CreateTable();
        await using (var context = new Context())
        {
            var list = await context.BirthDays.ToListAsync();
            foreach (var bd in list)
            {
                table.AddRow(
                    bd.Id.ToString(),
                    bd.FirstName,
                    bd.LastName,
                    bd.BirthDate.ToString(),
                    bd.YearsOld.ToString());
            }

            AnsiConsole.Write(table);
        }
        ExitPrompt();
    }
    public static Table CreateTable()
    {
        var table = new Table()
            .AddColumn("[b]Id[/]")
            .AddColumn("[b]First[/]")
            .AddColumn("[b]Last[/]")
            .AddColumn("[b]Birth date[/]")
            .AddColumn("[b]Age[/]")
            .Alignment(Justify.Left)
            .BorderColor(Color.LightSlateGrey);
        return table;
    }
}

上述程式碼的截圖

為了獲取我們的資料,一行程式碼用於實例化 EF Core,一行程式碼用於讀取資料。 EF Core 也非常適合關聯式資料庫,請參閱以下儲存庫

有關記錄 EF Core 產生的 SQL,請參閱下列專案,該專案也展示如何使用兩個不同的 SQL-Server 實例。

短小精悍的版本

{% cta https://github.com/karenpayneoregon/sql-basics/tree/master/DapperBirthdaysCompulatedColumns %} 範例專案 {% endcta %}

與 EF Core 不同,使用 Dapper,開發人員在 SSMS 中編寫 SQL 語句並將有效語句新增到程式碼中。有關 Dapper 的更多訊息,請參閱我的系列

這裡 SQL 儲存在唯讀字串中,替代方法是將 SQL(或任何語句)儲存在預存程序中。

學習編寫正確的 SQL

internal class SqlStatements
{
    public static string GetBirthdays =>
        """
        SELECT Id
            ,FirstName
            ,LastName
            ,BirthDate
            ,YearsOld
        FROM BirthDaysDatabase.dbo.BirthDays
        """;
}

讀取資料的程式碼。

internal class DapperOperations
{
    private IDbConnection _cn;

    public DapperOperations()
    {
        _cn = new SqlConnection(DataConnections.Instance.MainConnection);
        SqlMapper.AddTypeHandler(new SqlDateOnlyTypeHandler());
        SqlMapper.AddTypeHandler(new SqlTimeOnlyTypeHandler());
    }

    public async Task<List<BirthDays>> GetBirthdaysAsync()
    {
        return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList();
    }

}

在類別構造函數中

  1. 使用Microsoft.Data.SqlClient NuGet 套件建立連線。

  2. 使用kp.Dapper.Handlers NuGet 套件為 Dapper 新增理解 DateOnly 類型的功能。

讀取資料是一個單行資料,表示我們需要非同步生日列表。

public async Task<List<BirthDays>> GetBirthdaysAsync()
{
    return (await _cn.QueryAsync<BirthDays>(SqlStatements.GetBirthdays)).AsList();
}

回到 Program.cs,除了建立 Dapper 類別的實例並呼叫方法之外,程式碼與 EF Core 相同。

internal partial class Program
{
    static async Task Main(string[] args)
    {
        await Setup();

        var table = CreateTable();
        var operations = new DapperOperations();
        var list = await operations.GetBirthdaysAsync();
        foreach (var bd in list)
        {
            table.AddRow(
                bd.Id.ToString(),
                bd.FirstName, 
                bd.LastName, 
                bd.BirthDate.ToString(), 
                bd.YearsOld.ToString());
        }

        AnsiConsole.Write(table);

        ExitPrompt();
    }

    public static Table CreateTable()
    {
        var table = new Table()
            .AddColumn("[b]Id[/]")
            .AddColumn("[b]First[/]")
            .AddColumn("[b]Last[/]")
            .AddColumn("[b]Birth date[/]")
            .AddColumn("[b]Age[/]")
            .Alignment(Justify.Left)
            .BorderColor(Color.LightSlateGrey);
        return table;
    }
}

計算列的摘要

並未詳細介紹程式碼的每個方面,這意味著在專案中採用技術之前需要花時間剖析程式碼以及使用了哪些 NuGet 套件。也可以考慮透過Visual Studio 偵錯器執行程式碼。

偵錯是許多新手開發人員忽略的事情,也是 Visual Studio 的最佳功能之一。學習如何除錯並不需要花費大量時間。

第 2 課 - 重構程式碼

許多人認為編碼的主要任務是讓程式碼正常工作,然後返回並重構程式碼。從個人經驗來看,這種情況一般不會發生。這就是開發人員需要在工作專案之外磨練技能的原因。

從未停止學習

實施例1

開發人員被要求將字串拆分為大寫字符,並將字串放在前面。

例如,給定 ThisIsATest,輸出將是 This Is A Test。開發者在網路上搜尋並找到以下內容。

public static class StringExtensions
{
    private static readonly Regex CamelCaseRegex = new(@"([A-Z][a-z]+)");
    /// <summary>
    /// KarenPayne => Karen Payne
    /// </summary>
    [DebuggerStepThrough]
    public static string SplitCamelCase(this string sender) =>
        string.Join(" ", CamelCaseRegex.Matches(sender)
            .Select(m => m.Value));
}

這是可行的,但有一個更好的版本,在下面的範例中是由GitHub Copilot 編寫的,並且是第二次迭代,這意味著第一次copilot 被問到時,它提供了一個未經優化的解決方案,因為問題是如何提出的。

[DebuggerStepThrough]
public static string SplitCamelCase(this string input)
{
    if (string.IsNullOrEmpty(input))
    {
        return input;
    }

    Span<char> result = stackalloc char[input.Length * 2];
    var resultIndex = 0;

    for (var index = 0; index < input.Length; index++)
    {
        var currentChar = input[index];

        if (index > 0 && char.IsUpper(currentChar))
        {
            result[resultIndex++] = ' ';
        }

        result[resultIndex++] = currentChar;
    }

    return result[..resultIndex].ToString();
}

更少的程式碼並不總是最好的

等一下,第二個版本的程式碼多了很多,這個版本怎麼會更好呢?新手和經驗豐富的開發人員都有一種心態,就是程式碼行數越少越好,也許是為了提高可讀性。當然,開發人員應該始終努力編寫可讀的程式碼,但多行程式碼也可以輕鬆閱讀。

如何編寫可讀的程式碼。

  • 使用有意義的變數名稱,例如在 for 語句中使用索引而不是 i 或使用firstName 而不是fName。

  • 折疊程式碼而不是一行,如下所示

public static class CheckedListBoxExtensions
{
    public static List<T> CheckedList<T>(this CheckedListBox sender)
        => sender.Items.Cast<T>()
            .Where((_, index) => sender.GetItemChecked(index))
            .Select(item => item)
            .ToList();
}

而不是

public static class CheckedListBoxExtensions
{
    public static List<T> CheckedList<T>(this CheckedListBox sender)
        => sender.Items.Cast<T>().Where((_, index) => sender.GetItemChecked(index)).Select(item => item).ToList();
}

下一步

這裡有一些想法,即使是許多經驗豐富的開發人員也會避免,而不是你!

概括

這些是成為更好的開發人員的更多技巧中的一些。實現這一目標的唯一方法是在專案之外不斷學習。

如果您的老闆或團隊領導者沒有提供時間來學習新技能,您可以每週花一兩個小時來學習和成長。


原文出處:https://dev.to/karenpayneoregon/push-your-skills-2pho


共有 0 則留言