.NET প্রোপার্টি - ব্যক্তিগত সেট বা পঠনযোগ্য সম্পত্তি ব্যবহার করবেন?


45

কোন পরিস্থিতিতে কোনও প্রাইভেট সেট বনাম কোনও সম্পদকে কেবলমাত্র পঠনযোগ্য সম্পত্তি হিসাবে তৈরি করা উচিত? নীচের দুটি খুব সরল উদাহরণ বিবেচনা করুন।

প্রথম উদাহরণ:

Public Class Person

    Private _name As String

    Public Property Name As String
        Get
            Return _name
        End Get
        Private Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Public Sub WorkOnName()

        Dim txtInfo As TextInfo = _
            Threading.Thread.CurrentThread.CurrentCulture.TextInfo

        Me.Name = txtInfo.ToTitleCase(Me.Name)

    End Sub

End Class

// ----------

public class Person
{
    private string _name;
    public string Name
    {
        get { return _name; }
        private set { _name = value; }
    }

    public void WorkOnName()
    {
        TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
        this.Name = txtInfo.ToTitleCase(this.Name);
    }
}

দ্বিতীয় উদাহরণ:

Public Class AnotherPerson

    Private _name As String

    Public ReadOnly Property Name As String
        Get
            Return _name
        End Get
    End Property

    Public Sub WorkOnName()

        Dim txtInfo As TextInfo = _
            Threading.Thread.CurrentThread.CurrentCulture.TextInfo

        _name = txtInfo.ToTitleCase(_name)

    End Sub

End Class

// ---------------

public class AnotherPerson
{
    private string _name;
    public string Name
    {
        get { return _name; }
    }

    public void WorkOnName()
    {
        TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
        _name = txtInfo.ToTitleCase(_name);
    }
}

তারা উভয় একই ফলাফল দেয়। এটি কি এমন পরিস্থিতি যেখানে কোনও সঠিক এবং ভুল নেই এবং এটি কেবল পছন্দের বিষয়?


public string Name { get; protected set; }উত্তরাধিকার মাধ্যমে।
সামিস

উত্তর:


42

ব্যবহারের কয়েকটি কারণ রয়েছে private set

1) আপনি যদি কোনও সমর্থন ক্ষেত্র ব্যবহার না করেন এবং কেবল পঠনযোগ্য স্বয়ংক্রিয় সম্পত্তি চান:

public string Name { get; private set; }   

public void WorkOnName()
{
    TextInfo txtInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
    Name = txtInfo.ToTitleCase(Name);
}  

2) আপনি যদি আপনার শ্রেণীর অভ্যন্তরে পরিবর্তনশীল পরিবর্তন করতে চান এবং অতিরিক্ত কাজ করতে চান এবং সেটি একটি একক স্থানে ক্যাপচার করতে চান:

private string _name = string.Empty;
public string Name 
{ 
    get { return _name; }
    private set 
    {
        TextInfo txtInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
        _name = txtInfo.ToTitleCase(value);
    }
}

সাধারণভাবে যদিও এটি ব্যক্তিগত পছন্দের বিষয়। আমার জানা মতে, একে অপরকে ব্যবহার করার কোনও কার্যকারিতা কারণ নেই।


1
কেবল এটি যুক্ত করা কারণ প্রশ্নটির একটি ভিবি নেট ট্যাগ রয়েছে, তবে ভিবি.net তে আপনাকে একটি বেসর নির্দিষ্ট করতে হবে যদি আপনি হয় হয় বা সেট হয় প্রাইভেট ব্যবহার করেন। সুতরাং vb.net এ সম্পত্তিটি কেবলমাত্র পঠনযোগ্যভাবে তৈরি করা কম কাজ
ব্যবহারকারী 643192

আমি কখনই সে সম্পর্কে জানতাম না private set। :-)
আফজাল আহমদ জিশান

9
2016. সি # 6.0 এই উত্তরটি পড়া তাদের জন্য একটি আপডেট চালু করেছে কেবলমাত্র স্বয়ংক্রিয় বৈশিষ্ট্য, যা আপনি একটি ব্যাকিং ক্ষেত্র ছাড়া একটি কেবল পঠনযোগ্য বিশিষ্টতা আছে মঞ্জুরি দিন: public string Name { get; }। আপনি যদি কোনও পরিবর্তনীয় সম্পত্তি না চান, এটি এখন পছন্দসই সিনট্যাক্স।
অ্যালেক্সি

4
ব্যবহার না করার একটি খুব ভাল কারণ private setহ'ল এটির মতো অপরিবর্তনীয় নয় যা আমরা এটির ভান করতে চাই। আপনি যদি সত্যিকারের অপরিবর্তনীয় শ্রেণি বাস্তবায়ন করতে চান তবে কেবল পঠন করা আবশ্যক।
রাবারডাক

কেবলমাত্র পঠনযোগ্য ব্যবহার না করার পারফরম্যান্সের কারণ হতে পারে। যখন কেবলমাত্র পঠনযোগ্য স্ট্রাক্ট ক্ষেত্রের পদ্ধতিতে অ্যাক্সেস করা হয় তখন স্ট্রোকগুলি অনুলিপি করে অনুলিপি তৈরি করে। codeblog.jonskeet.uk/2014/07/16/…
ট্রায়ঙ্কো

28

বেসরকারী সেট ব্যবহার করুন যখন আপনি সেটটার বাইরে থেকে অ্যাক্সেস করতে পারবেন না

আপনি কেবল একবার সম্পত্তি সেট করতে চাইলে কেবল পঠনযোগ্য ব্যবহার করুন । কনস্ট্রাক্টর বা ভেরিয়েবল ইনিশিয়ালাইজারে।

এটি পরীক্ষা করুন:

void Main()
{
    Configuration config = new Configuration();
    config.ResetConfiguration();

    ConfigurationReadOnly configRO = new ConfigurationReadOnly();
    configRO.ResetConfiguration();
}

public class Configuration
{
    public Color BackgroundColor { get; private set; }
    public Color ForegroundColor { get; private set; }
    public String Text { get; private set; }

    public Configuration()
    {
        BackgroundColor = Color.Black;
        ForegroundColor = Color.White;
        Text = String.Empty;
    }

    public void ResetConfiguration()
    {
        BackgroundColor = Color.Black;
        ForegroundColor = Color.White;
        Text = String.Empty;
    }
}

public class ConfigurationReadOnly
{
    public readonly Color BackgroundColor;
    public readonly Color ForegroundColor;
    public readonly String Text;

    public ConfigurationReadOnly()
    {
        BackgroundColor = Color.Black;
        ForegroundColor = Color.White;
        Text = String.Empty;
    }

    public void ResetConfiguration()
    {
        BackgroundColor = Color.Black; // compile error: due to readonly keyword
        ForegroundColor = Color.White; // compile error: due to readonly keyword
        Text = String.Empty; // compile error: due to readonly keyword
    }
}

যদিও আমি আপনার উত্তরের সাথে একমত, আপনার উদাহরণটি কিছু উন্নতি করতে পারে। সংকলক ত্রুটি ঘটবে যেখানে আপনি একটি মন্তব্য করতে চাইতে পারেন।
মাইকেল রিচার্ডসন

এনবি সি # readonlyকীওয়ার্ডের সাথে সম্পর্কিত VB.NET সিনট্যাক্সটি ReadOnlyসম্পত্তিটির পরিবর্তে ক্ষেত্রটিতে প্রয়োগ করতে হবে।
জেভ স্পিটজ

8

আমি কি তৃতীয় বিকল্পের পরামর্শ দিতে পারি?

public class Person
{
    public string Name { get; protected set; }

    public void SetName(string name)
    {
        TextInfo txtInfo = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo;
        this.Name = txtInfo.ToTitleCase(name);
    }
}

এটি নাম বৈশিষ্ট্যটিকে কার্যকরভাবে কেবলমাত্র বাইরের সমস্ত কোডে পঠন করে এবং একটি সুস্পষ্ট সেট পদ্ধতি সরবরাহ করে। আমি নাম বৈশিষ্ট্যের উপর সেটটি কেবল ব্যবহার না করে সুস্পষ্ট সেটটিকে পছন্দ করি কারণ এটি সেট করার সময় আপনি মানটি পরিবর্তন করছেন। সাধারণত আপনি সেট একটি সম্পত্তি মান, আপনি একই মান ফিরে পেতে আপনি কল যখন আশা পেতে পরে, যা আপনি আপনার ToTitleCase করেনি ঘটতে না সেট

তবে, আপনি যেমন বলেছিলেন, সঠিক উত্তর নেই no


আমি বিশ্বাস করি যে 'প্রাইভেট সেট' এর কম্পাইলারে বিশেষ শব্দার্থক রয়েছে (কেবলমাত্র প্রাইভেট অ্যাক্সেসর হিসাবে সম্পাদন করা হচ্ছে না)। এটি কি সুরক্ষিত সেট ক্ষেত্রে? যদি তা না হয় তবে প্রাইভেট সেটে যদি বিশেষ শব্দার্থবিদ্যা থাকে তবে সুরক্ষিত সেটের সমার্থক সমতুল্য কোথায়? এটির ব্যাখ্যা দিয়ে আমি কোনও ডকুমেন্টেশন খুঁজে পাইনি।
স্প্রেগ করুন

1
+1 তবে আমি "সেট নাম" এর পরিবর্তে পদ্ধতিটিকে "পুনরায় নামকরণ" বলব।
ম্যাটড্যাভি

5

সি # 6.0 থেকে শুরু করে, গেটর-কেবল অটো বৈশিষ্ট্যগুলি ভাষায় যুক্ত করা হয়েছে। এখানে দেখুন: https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#getter-only-auto-properties

এখানে একটি উদাহরণ:

public class SomeClass
{
    public int GetOnlyInt { get; }

    public int GetOnlyIntWithInitializer { get; } = 25;

    public SomeClass(int getOnlyInt)
    {
        GetOnlyInt = getOnlyInt;
    }
}

4

দ্বিতীয় উদাহরণ ব্যবহার করবেন না। কোনও সম্পত্তি ব্যবহারের পুরো বিষয়টি - এমনকি গেটর পাবার এবং সেটার সেটিংয়ের বাইরে কিছু না হলেও - সেই গেটর এবং সেটারের মাধ্যমে সমস্ত অ্যাক্সেস ফানেল করা যাতে ভবিষ্যতে আপনার যদি কখনও আচরণ পরিবর্তন করার প্রয়োজন হয় তবে তা সবই আছে এক জায়গায়.

আপনার দ্বিতীয় উদাহরণ সম্পত্তি নির্ধারণের ক্ষেত্রে এটি ত্যাগ করে। যদি আপনি এই পদ্ধতিটি একটি বৃহত, জটিল শ্রেণিতে ব্যবহার করেন এবং পরে সম্পত্তির আচরণ পরিবর্তন করার প্রয়োজন হয়, তবে আপনি এক জায়গায় পরিবর্তন না করে স্থল-সন্ধান এবং প্রতিস্থাপনের জায়গায় থাকবেন - ব্যক্তিগত সেটটার।


2

যখনই আমার কোনও সেটারের অ্যাক্সেসের স্তরটি পরিবর্তন করার দরকার পড়েছে, আমি সাধারণত এটি প্রোটেক্টেড (কেবলমাত্র এই শ্রেণি এবং উত্পন্ন শ্রেণিগুলির মান পরিবর্তন করতে পারে) বা বন্ধু (কেবলমাত্র আমার সমাবেশের সদস্যরা মানটি পরিবর্তন করতে পারে) এ পরিবর্তন করেছি।

আপনি যখন ব্যাকিংয়ের মান পরিবর্তন করার পাশাপাশি সেটারে অন্য কাজগুলি করতে চান তখন ব্যক্তিগত ব্যবহারটি সঠিকভাবে বোঝায়। যেমনটি আগে উল্লেখ করা হয়েছে, আপনার ব্যাকিং মানগুলি সরাসরি না উল্লেখ করা বরং এটি কেবল তাদের সম্পত্তিগুলির মাধ্যমে অ্যাক্সেস করা ভাল নকশা। এটি নিশ্চিত করে যে কোনও সম্পত্তিতে পরে করা পরিবর্তনগুলি অভ্যন্তরীণ পাশাপাশি এবং বাহ্যিকভাবে প্রয়োগ করা হয়। এবং কোনও সম্পত্তি এর ব্যাকিং ভেরিয়েবল উল্লেখ করার জন্য কার্যত কোনও পারফরম্যান্স পেনাল্টি নেই।


0

এবং কার্যত কোনও পারফরম্যান্স পেনাল্টি নেই ...

কিন্তু নির্মল, একটি সম্পত্তি অ্যাক্সেস হয় তার ব্যাকিং পরিবর্তনশীল অ্যাক্সেস তুলনায় ধীর। কোনও সম্পত্তির গেটর এবং সেটার এমন একটি পদ্ধতি যা কল এবং রিটার্ন প্রয়োজন, যেখানে কোনও সম্পত্তির ব্যাকিং ভেরিয়েবলটি সরাসরি অ্যাক্সেস করা হয়।

এ কারণেই, যে কোনও ক্ষেত্রে কোনও ব্লকের কোডের মধ্যে কোনও সম্পত্তির প্রাপ্তকারী অনেকবার অ্যাক্সেস করতে পারে, সেই ক্ষেত্রে সম্পত্তিটির মান কখনও কখনও প্রথমে ক্যাশে হয় (স্থানীয় ভেরিয়েবলে সংরক্ষণ করা হয়) এবং এর পরিবর্তে স্থানীয় ভেরিয়েবল ব্যবহৃত হয়। অবশ্যই, এটি ধরে নিয়েছে যে ব্লকটি সম্পাদন করার সময় সম্পত্তিটি তাত্পর্যপূর্ণভাবে পরিবর্তন করা যাবে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.