فرق بین class و record در سیشارپ

👈 در این مقاله به تفاوت های بین class و record در سیشارپ میپردازیم.


👁 بازدید : 112

1402/12/3 | 15:10 : تاریخ 📆


هم کلاس و هم record هر دو برای ایجاد دیتا استراکچر یا ساختار داده استفاده میشن، اما با هم تفاوت هایی دارن :(سعی میکنم در این مقاله از اصطلاحات برنامه نویسی استفاده کنم بجای ترجمه)

     1.مقادیر کلاس قابل تغییر یا به اصطلاح mutable هستند ولی مقادیر record را نمیتوتیم تغییر بدیم یا به اصطلاح immutable هستن.

          بیایید یه مثال ببینیم :

public class Person1{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public record Person2(string firstName,string lastName);
class Program
{
    static void Main(string[] args)
    {
            var p1 = new Person1();
            var p2 = new Person2("saeed","balkani");
            p1.FirstName = "ali";
            p1.LastName ="alavi";
            // *************** //
            p1.FirstName = "reza";
            p1.LastName ="rezaie";
            p2.firstName = "pedram"; //In This Line We Have Error
    }
}

در اینجا یک کلاس و یک record تعریف کردیم و مقادیر مورد نیاز به شی داده شده اما در لحظه ایی که قصد تغییر مقادیر قبلی را داشتیم پراپرتی های کلاس تغییر کرده اما پرارپتی های record با خطا مواجه شده.

در نظر داشته باشید هر چیزی که داخل پرانتز در recordها نوشته بشه، به صورت اتوماتیک تبدیل به پراپرتی میشه.

     2. recordها برابری value-based دارند:

public class Person1{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public record Person2(string firstName,string lastName);

class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1();
        var p1_1 = new Person1();
        var p2 = new Person2("saeed","balkani");
        var p2_2 = new Person2("saeed","balkani");
        Console.WriteLine(p1 == p1_1); //This Line Is False
        Console.WriteLine(p2 == p2_2); //This Line Is True
    }
}

طبق کد بالا با هر نمونه سازی از کلاس، یک شی جدید ساخته میشه که با شی قبلی برابر نیست، اما این موضوع در record کاملا برعکسه.فقط به یاد داشته باشید اگر این کد رو

  var p2_2 = new Person2("ali","alavi");

جایگزین کد بالا کنیم برابری از بین میرود.

     3. recordها میتونن داخل کلاس قرار بگیرن :

public class Person1{
    public FullName Name { get; set; }
    public string City { get; set; }
    public record FullName(string firstName,string lastName);
}


class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1{Name = new Person1.FullName("saeed","balkani"),City="Tehran"};
        Console.WriteLine(p1.Name);
    }
}

//*********** OR **********

public class Person1{
    public FullName Name { get; set; }
    public string City { get; set; }
}
public record FullName(string firstName,string lastName);

class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1{Name = new FullName("saeed","balkani"),City="Tehran"};
        Console.WriteLine(p1.Name);
    }
}

     4. استفاده از عبارت with :

گاهی اوقات لازمه یک یا تعداد کمی از پراپرتی ها مقدار متفاوتی داشته باشن،این کار در کلاس با زحمت زیادی همراه میشه اما در record خیلی ساده از عبارت with  استفاده میکنیم.

public class Person 
{
   public FullName FullName { get; set; }
}
public record FullName(string FirstName, string LastName);
class Program
{
  static void Main(string[] args)
  {
    var person1 = new Person { FullName = new FullName("saeed", "balkani") };
    var person2 = new Person { FullName = person1.FullName };
            
    Console.WriteLine(person1.FullName );
    person2.FullName = person2.FullName with { FirstName = "alizadeh"} ;
    Console.WriteLine(person2.FullName);
    Console.WriteLine(person1.FullName );
  }
}

 جالبه بدونید که قبلا گفتیم recordها immutable یا تغییر ناپذیر هستن ولی خب چطور ایجا مقدار تغییر کرد!؟

بله، جریان از این قراره که وقتی یک record ساخته و به اون پراپرتی اضافه میشه، در واقع هیچ setterایی در اون وجود نداره. بجاش init  سروکلش پیدا میشه. در واقع در کد زیر FirstName و LastName اینجوری در record ساخته میشن:

          public record FullName(string FirstName, string LastName);
        //                                    |               |
public string FirstName { get; init; } //-----|               |
public string LastName { get; init; } //----------------------|

اما در کلاس Person چون ما به پراپرتی FullName کلمه set اضافه کردیم، پس record ما قابل تغییر خواهد بود.اگر نخواهیم record ما تغییر کنه فقط کافیه بهش init اضافه کنیم.مثل کد زیر:

public class Person 
{
   public FullName FullName { get; init; }
}
public record FullName(string FirstName, string LastName);

 

به طور کلی، زمانی که به یک دیتا استراکچر ساده که تغییر ناپذیر باشد احتیاج داشته باشید، باید از یک رکورد استفاده کنید. زمانی که به دیتا استراکچر پیچیده تری نیاز دارید که ممکن است نیاز به تغییر داشته باشد، باید از یک کلاس استفاده کنید.

با این حال، شایان ذکر است که هم کلاس ها و هم recordها اهداف متفاوت و موارد استفاده خاص خود را دارند. کلاس‌ها هنوز هم برای تعریف رفتارهای پیچیده، مدل‌سازی موجودیت‌ها یا اجرای اصول OOP انتخاب ارجح هستند، در حالی که recordها بیشتر بردیتا استراکچرهای تغییرناپذیر و برابری value-based متمرکز هستند.

این مقاله بزودی آپدیت و موارد جدیدتری اضافه خواهد شد...

هم کلاس و هم record هر دو برای ایجاد دیتا استراکچر یا ساختار داده استفاده میشن، اما با هم تفاوت هایی دارن :(سعی میکنم در این مقاله از اصطلاحات برنامه نویسی استفاده کنم بجای ترجمه)

     1.مقادیر کلاس قابل تغییر یا به اصطلاح mutable هستند ولی مقادیر record را نمیتوتیم تغییر بدیم یا به اصطلاح immutable هستن.

          بیایید یه مثال ببینیم :

public class Person1{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public record Person2(string firstName,string lastName);
class Program
{
    static void Main(string[] args)
    {
            var p1 = new Person1();
            var p2 = new Person2("saeed","balkani");
            p1.FirstName = "ali";
            p1.LastName ="alavi";
            // *************** //
            p1.FirstName = "reza";
            p1.LastName ="rezaie";
            p2.firstName = "pedram"; //In This Line We Have Error
    }
}

در اینجا یک کلاس و یک record تعریف کردیم و مقادیر مورد نیاز به شی داده شده اما در لحظه ایی که قصد تغییر مقادیر قبلی را داشتیم پراپرتی های کلاس تغییر کرده اما پرارپتی های record با خطا مواجه شده.

در نظر داشته باشید هر چیزی که داخل پرانتز در recordها نوشته بشه، به صورت اتوماتیک تبدیل به پراپرتی میشه.

     2. recordها برابری value-based دارند:

public class Person1{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public record Person2(string firstName,string lastName);

class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1();
        var p1_1 = new Person1();
        var p2 = new Person2("saeed","balkani");
        var p2_2 = new Person2("saeed","balkani");
        Console.WriteLine(p1 == p1_1); //This Line Is False
        Console.WriteLine(p2 == p2_2); //This Line Is True
    }
}

طبق کد بالا با هر نمونه سازی از کلاس، یک شی جدید ساخته میشه که با شی قبلی برابر نیست، اما این موضوع در record کاملا برعکسه.فقط به یاد داشته باشید اگر این کد رو

  var p2_2 = new Person2("ali","alavi");

جایگزین کد بالا کنیم برابری از بین میرود.

     3. recordها میتونن داخل کلاس قرار بگیرن :

public class Person1{
    public FullName Name { get; set; }
    public string City { get; set; }
    public record FullName(string firstName,string lastName);
}


class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1{Name = new Person1.FullName("saeed","balkani"),City="Tehran"};
        Console.WriteLine(p1.Name);
    }
}

//*********** OR **********

public class Person1{
    public FullName Name { get; set; }
    public string City { get; set; }
}
public record FullName(string firstName,string lastName);

class Program
{
    static void Main(string[] args)
    {
        var p1 = new Person1{Name = new FullName("saeed","balkani"),City="Tehran"};
        Console.WriteLine(p1.Name);
    }
}

     4. استفاده از عبارت with :

گاهی اوقات لازمه یک یا تعداد کمی از پراپرتی ها مقدار متفاوتی داشته باشن،این کار در کلاس با زحمت زیادی همراه میشه اما در record خیلی ساده از عبارت with  استفاده میکنیم.

public class Person 
{
   public FullName FullName { get; set; }
}
public record FullName(string FirstName, string LastName);
class Program
{
  static void Main(string[] args)
  {
    var person1 = new Person { FullName = new FullName("saeed", "balkani") };
    var person2 = new Person { FullName = person1.FullName };
            
    Console.WriteLine(person1.FullName );
    person2.FullName = person2.FullName with { FirstName = "alizadeh"} ;
    Console.WriteLine(person2.FullName);
    Console.WriteLine(person1.FullName );
  }
}

 جالبه بدونید که قبلا گفتیم recordها immutable یا تغییر ناپذیر هستن ولی خب چطور ایجا مقدار تغییر کرد!؟

بله، جریان از این قراره که وقتی یک record ساخته و به اون پراپرتی اضافه میشه، در واقع هیچ setterایی در اون وجود نداره. بجاش init  سروکلش پیدا میشه. در واقع در کد زیر FirstName و LastName اینجوری در record ساخته میشن:

          public record FullName(string FirstName, string LastName);
        //                                    |               |
public string FirstName { get; init; } //-----|               |
public string LastName { get; init; } //----------------------|

اما در کلاس Person چون ما به پراپرتی FullName کلمه set اضافه کردیم، پس record ما قابل تغییر خواهد بود.اگر نخواهیم record ما تغییر کنه فقط کافیه بهش init اضافه کنیم.مثل کد زیر:

public class Person 
{
   public FullName FullName { get; init; }
}
public record FullName(string FirstName, string LastName);

 

به طور کلی، زمانی که به یک دیتا استراکچر ساده که تغییر ناپذیر باشد احتیاج داشته باشید، باید از یک رکورد استفاده کنید. زمانی که به دیتا استراکچر پیچیده تری نیاز دارید که ممکن است نیاز به تغییر داشته باشد، باید از یک کلاس استفاده کنید.

با این حال، شایان ذکر است که هم کلاس ها و هم recordها اهداف متفاوت و موارد استفاده خاص خود را دارند. کلاس‌ها هنوز هم برای تعریف رفتارهای پیچیده، مدل‌سازی موجودیت‌ها یا اجرای اصول OOP انتخاب ارجح هستند، در حالی که recordها بیشتر بردیتا استراکچرهای تغییرناپذیر و برابری value-based متمرکز هستند.

این مقاله بزودی آپدیت و موارد جدیدتری اضافه خواهد شد...

هنوز دیدگاهی ثبت نشده

تمامی‌حقوق‌مادی‌ومعنوی‌این‌سایت‌برای‌یادمیگیریم‌محفوظ است.