ক্লাস এ-তে কোনও সম্পত্তি কীভাবে প্রয়োগ করা যায় যা শ্রেণি এ এর ​​শিশু সামগ্রীর সম্পত্তি বোঝায়


9

আমাদের কাছে এই কোডটি রয়েছে যা সরলীকরণের পরে দেখায়:

public class Room
{
    public Client Client { get; set; }

    public long ClientId
    {
        get
        {
            return Client == null ? 0 : Client.Id;
        }
    }
}

public class Client 
{
    public long Id { get; set; }
}

এখন আমাদের তিনটি দৃষ্টিভঙ্গি রয়েছে।

1) এটি ভাল কোড কারণ Clientসম্পত্তি সর্বদা সেট করা উচিত (অর্থাত নাল নয়) সুতরাং Client == nullকখনই ঘটবে না এবং আইডি মানটি 0যাইহোক একটি মিথ্যা আইডিকে চিহ্নিত করে (এটি কোডের লেখকের মতামত ;-))

২) আপনি কলারের উপর নির্ভর করতে পারবেন না যে এটির জন্য 0একটি ভ্রান্ত মূল্য Idএবং Clientসম্পত্তি যখন সর্বদা সেট করা উচিত তখন যখন সম্পত্তিটি নালার দিকে exceptionযায় getতখন আপনাকে একটি নিক্ষেপ করা উচিতClient

3) Clientসম্পত্তিটি সর্বদা সেট করা উচিত যখন আপনি কেবল ফিরে Client.Idআসুন NullRefএবং Clientসম্পত্তিটি শূন্য হয়ে যাওয়ার পরে কোডটি একটি ব্যতিক্রম ছুঁড়তে দিন ।

এর মধ্যে কোনটি সবচেয়ে সঠিক? নাকি চতুর্থ সম্ভাবনা আছে?


5
কোনও উত্তর নয়, কেবল একটি নোট: সম্পত্তি প্রাপ্তিদের থেকে কখনও ব্যতিক্রম ছুঁড়ে ফেলবেন না।
ব্র্যান্ডন 14

3
: ব্রান্ডন এর বিন্দুতে সম্প্রসারিত stackoverflow.com/a/1488488/569777
MetaFight

1
নিশ্চিত: সাধারণ ধারণা ( এমএসডিএন.মাইক্রোসফটকম / en- us / library/… , অন্যদের মধ্যে স্ট্যাকওভারফ্লো / প্রশ্ন / 1488472/… ,) বৈশিষ্ট্যগুলি যতটা সম্ভব কম করা উচিত, হালকা হওয়া উচিত এবং পরিষ্কারের প্রতিনিধিত্ব করা উচিত আপনার সূচকের সামান্য ব্যতিক্রম হ'ল আপনার অবজেক্টের সর্বজনীন মুখোমুখি অবস্থা। ডিবাগিংয়ের সময় কোনও সম্পত্তির জন্য ওয়াচ উইন্ডোয় ব্যতিক্রমগুলি দেখার জন্য এটি অপ্রত্যাশিত আচরণ।
ব্র্যান্ডন

1
আপনার কোনও কোড লিখতে হবে না (যা দরকার নেই) যা কোনও সম্পত্তি গেটের মধ্যে ফেলে দেয়। এর অর্থ এই নয় যে কোনও বস্তু অসমর্থিত অবস্থায় যাওয়ার কারণে ঘটে যাওয়া কোনও ব্যতিক্রমগুলি আপনাকে লুকিয়ে রাখতে এবং গিলে ফেলতে হবে।
বেন

4
আপনি কেবল রুম.ক্লায়েন্ট.আইডি করতে পারবেন না কেন? আপনি কেন এটি রুমে মুড়ে রাখতে চান? ক্লায়েন্টআইডি? যদি এটি কোনও ক্লায়েন্টের জন্য যাচাই করা হয় তবে কেন রুমের মতো কিছু নয় as হ্যাসক্লিয়েন্ট {get {রিটার্ন ক্লায়েন্ট == নাল; } more এটি আরও সোজা এগিয়ে রয়েছে এবং এখনও লোকেরা সাধারণ কক্ষটি করতে দেয় li
জেমস

উত্তর:


25

এটির গন্ধে মনে হচ্ছে আপনার Roomক্লাসটি যে রাজ্যে থাকতে পারে তার সংখ্যা সীমাবদ্ধ করা উচিত ।

Clientনাল যখন আপনি কি করতে হবে সম্পর্কে খুব জিজ্ঞাসা একটি ইঙ্গিত যে Roomএর রাজ্যের স্থান খুব বড়।

জিনিসগুলি সহজ রাখার জন্য আমি কোনও সংস্থার Clientসম্পত্তি Roomকখনও নালার অনুমতি দেব না । তার মানে এর মধ্যে থাকা কোডটি Roomনিরাপদে ধরে নিতে পারে যে Clientএটি কখনই বাতিল নয়।

ভবিষ্যতে কোনো কারণে যদি Clientহয়ে nullআবেগ যে রাষ্ট্র সমর্থন করার জন্য প্রতিরোধ। এটি করা আপনার রক্ষণাবেক্ষণের জটিলতা বাড়িয়ে তুলবে।

পরিবর্তে, কোডটি ব্যর্থ হতে এবং দ্রুত ব্যর্থ হওয়ার অনুমতি দিন। সর্বোপরি, এটি কোনও সমর্থিত রাষ্ট্র নয়। যদি অ্যাপ্লিকেশনটি এই অবস্থায় চলে যায় তবে আপনি ইতিমধ্যে কোনও রিটার্নের একটি লাইন অতিক্রম করেছেন। এরপরে একমাত্র যুক্তিযুক্ত জিনিসটি হল অ্যাপ্লিকেশনটি বন্ধ করা।

আনহ্যান্ডেল নাল রেফারেন্স ব্যতিক্রমের ফলাফল হিসাবে এটি হতে পারে (বেশ স্বাভাবিকভাবেই)।


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

@ মিশেল যদি আপনি পরে এই প্রয়োজনীয়তাটি পরিবর্তন করার সিদ্ধান্ত নেন, আপনি nullমানটি একটি NullObject(বা বরং NullClient) দিয়ে প্রতিস্থাপন করতে পারেন যা এখনও আপনার বিদ্যমান কোডের সাথে কাজ করবে এবং প্রয়োজনে অস্তিত্বহীন ক্লায়েন্টের জন্য আচরণের সংজ্ঞা দেওয়ার অনুমতি দেবে। প্রশ্নটি যদি "কোনও ক্লায়েন্ট" কেসটি ব্যবসায়ের যুক্তির অংশ হয় বা না হয়।
নর্থ

3
সম্পূর্ণ সঠিক। একটি অসমর্থিত রাষ্ট্র সমর্থন করতে কোডের একটি অক্ষর লিখবেন না। শুধু এটি একটি নালরফ নিক্ষেপ করা যাক।
বেন

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

1
@ এবং গাইডলাইনটির কারণ বুঝতে পেরে আপনি কখন তা প্রয়োগ হয় না তা জানতে পারবেন।
বেন

21

মাত্র কয়েকটি বিবেচনা:

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

খ) দ্বিতীয় মতামত সম্পর্কে আপনি একটি ধ্রুবক পরিচয় করিয়ে দিতে পারেন Invalid_Client_Id

গ) এক এবং তিনজনের মতামত সম্পর্কে (এবং আমার মূল বিষয় হচ্ছে): একটি ঘরে সর্বদা ক্লায়েন্ট থাকা উচিত? হতে পারে এটি কেবল শব্দার্থক তবে এটি সঠিক শোনাচ্ছে না। রুম এবং ক্লায়েন্ট এবং অন্য ক্লাসের জন্য একে অপরের সাথে সম্পূর্ণ আলাদা ক্লাস করা আরও উপযুক্ত হবে। হতে পারে অ্যাপয়েন্টমেন্ট, রিজার্ভেশন, দখল? (এটি আপনি আসলে যা করছেন তার উপর নির্ভর করে)) এবং সেই শ্রেণীর উপর আপনি "একটি কক্ষ থাকতে হবে" এবং "অবশ্যই একটি ক্লায়েন্ট থাকা উচিত" সীমাবদ্ধতাগুলি প্রয়োগ করতে পারেন।


5
+1 "আমি দেখতে পাই না যেমন ক্লায়েন্টআইডি দীর্ঘকালীন তথ্যটি কেন রুমের স্বাক্ষরে পাথরে খোদাই করতে হবে"
মিশেল

আপনার ইংরেজি ভাল আছে। ;) কেবল এই উত্তরটি পড়ে, আমি জানতাম না যে আপনি না বলে আপনার মাতৃভাষা ইংরেজি নয়।
jpmc26

পয়েন্ট বি এবং সি ভাল; আর: এ, এটি একটি সুবিধার পদ্ধতি এবং রুমটি ক্লায়েন্টের সাথে উল্লেখ করার বিষয়টি কেবল একটি বাস্তবায়নের বিশদ হতে পারে (এটি যুক্তিযুক্ত হতে পারে যে ক্লায়েন্টটি সর্বজনীনভাবে দৃশ্যমান হওয়া উচিত নয়)
অ্যান্ডি

17

আমি তিনটি মতামতের সাথে একমত নই। যদি Clientকরতে পারেন হতে null, তারপর এটা সম্ভব এটা হতে জন্য নাnull !

  1. Clientকনস্ট্রাক্টরের মান নির্ধারণ করুন
  2. ArgumentNullExceptionকনস্ট্রাক্টরে একটি নিক্ষেপ করুন ।

সুতরাং আপনার কোড কিছু হবে:

public class Room
{
    private Client theClient;

    public Room(Client client) {
        if(client == null) throw new ArgumentNullException();
        this.theClient = client;
    }

    public Client Client { 
        get { return theClient; }
        set 
        {
            if (value == null) 
                throw new ArgumentNullException();
            theClient = value;
        }
    }

    public long ClientId
    {
        get
        {
            return theClient.Id;
        }
    }
}
public class Client 
{
    public long Id { get; set; }
}

এটি আপনার কোডের সাথে সম্পর্কিত নয়, তবে সম্ভবত আপনি তৈরির মাধ্যমে একটি অপরিবর্তনীয় সংস্করণ ব্যবহার করা ভাল এবং তারপরে ক্লায়েন্ট যদি নতুন ঘর তৈরি করে পরিবর্তন করে। এটি আমার উত্তরের অন্যান্য দিকগুলির নাল সুরক্ষা ছাড়াও আপনার কোডের থ্রেড সুরক্ষা উন্নত করবে। পরিবর্তনীয় বনাম অপরিবর্তনীয় সম্পর্কে এই আলোচনাটি দেখুনRoomtheClient readonly


1
এগুলি করা উচিত নয় ArgumentNullException?
ম্যাথিউ গুইন্ডন

4
নং প্রোগ্রাম কোডটি কখনই একটি নিক্ষেপ করা উচিত নয় NullReferenceException, এটি নেট ভিএম দ্বারা নিক্ষেপ করা হয় "যখন কোনও নাল অবজেক্ট রেফারেন্সকে অবজ্ঞার চেষ্টা করা হয়" । আপনার একটি নিক্ষেপ করা উচিত ArgumentNullException, যা নিক্ষেপ করা হয় "যখন নাল রেফারেন্স (কিছুই নয় ভিজুয়াল বেসিক) এমন পদ্ধতিতে পাস করা হয় যা এটিকে বৈধ যুক্তি হিসাবে স্বীকার করে না।"
ফারাপ

2
@ ফারাপ আমি জাভা প্রোগ্রামার, সি # কোড লেখার চেষ্টা করছি, আমি বুঝতে পেরেছিলাম যে আমিও এর মতো ভুল করেছি।
durron597

@ durron597 আমার অনুমান করা উচিত ছিল যে 'চূড়ান্ত' শব্দটি ব্যবহার করা থেকে (এই ক্ষেত্রে সংশ্লিষ্ট সি # কীওয়ার্ডটি হ'ল readonly)। আমি সবেমাত্র সম্পাদনা করতাম তবে আমি অনুভব করেছি যে একটি মন্তব্য কেন (ভবিষ্যতের পাঠকদের জন্য) আরও ভাল তা ব্যাখ্যা করতে সক্ষম হবে। আপনি যদি ইতিমধ্যে এই উত্তর না দিয়ে থাকেন তবে আমি ঠিক একই সমাধান দিচ্ছি। অপরিচ্ছন্নতাও একটি ভাল ধারণা, তবে এটি সর্বদা একজনের আশার মতো সহজ নয়।
ফারাপ

2
সম্পত্তি সাধারণত ব্যতিক্রম নিক্ষেপ করা উচিত নয়; আরগমেন্ট নলএক্সসেপশন ছুঁড়ে এমন একটি সেটার পরিবর্তে পরিবর্তে একটি সেটক্লিয়েন্ট পদ্ধতি সরবরাহ করুন। কেউ এই প্রশ্নের উপর একটি উত্তর লিঙ্ক পোস্ট করেছেন।
অ্যান্ডি

5

দ্বিতীয় এবং তৃতীয় বিকল্পগুলি এড়ানো উচিত - গ্রাহককে কলারের উপর কোনও নিয়ন্ত্রণ না থাকা ব্যতীত স্ম্যাক করা উচিত নয়।

ক্লায়েন্ট কখনও নਾਲ হতে পারে কিনা তা আপনার সিদ্ধান্ত নেওয়া উচিত। যদি তাই হয় তবে আপনার কলার অ্যাক্সেস করার আগে এটি বাতিল কিনা তা যাচাই করার জন্য আপনার একটি উপায় সরবরাহ করা উচিত (উদাহরণস্বরূপ, বুল ক্লায়েন্টআইনল সম্পত্তি)।

আপনি যদি স্থির করেন যে ক্লায়েন্ট কখনই নਾਲ হতে পারে না, তারপরে এটি নির্মাতার কাছে প্রয়োজনীয় প্যারামিটার তৈরি করুন এবং যদি কোনও নাল প্রবেশ করে তবে ব্যতিক্রম সেখানে ফেলে দিন throw

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

long clientId = room.Client.Id;

যদি ক্লায়েন্ট শূন্য হতে পারে তবে আপনি কমপক্ষে কলকারীকে দায়িত্ব দেবেন:

if (room.Client != null){
    long clientId = room.Client.Id;
    /* other code follows... */
}

1
আমি মনে করি "ক্লায়েন্ট ইতিমধ্যে যে সমস্ত প্রস্তাব দিচ্ছেন তার সবই নকল করে ফেলবেন" সাহসী বা কমপক্ষে তাত্পর্যপূর্ণ হওয়া দরকার।
ফারাপ

2

যদি নাল ক্লায়েন্টের সম্পত্তিটি একটি সমর্থিত রাষ্ট্র হয় তবে নুলবজেক্টটি ব্যবহার করার বিষয়টি বিবেচনা করুন ।

তবে সম্ভবত এটি একটি ব্যতিক্রমী রাষ্ট্র, সুতরাং আপনার শূন্যতা অবধি শেষ করা অসম্ভব (বা কেবল খুব সুবিধাজনক নয়) হওয়া উচিত Client:

public Client Client { get; private set; }

public Room(Client client)
{
    Client = client;
}

public void SetClient(Client client)
{
    if (client == null) throw new ArgumentNullException();
    Client = client;
}

যদি এটি সমর্থিত না হয় তবে অর্ধ বেকড সমাধানগুলিতে সময় নষ্ট করবেন না। এক্ষেত্রে:

return Client == null ? 0 : Client.Id;

আপনি নুলারফেরান এক্সেক্সশনটি এখানে 'সমাধান' করেছেন তবে একটি দুর্দান্ত ব্যয়ে! এটি সমস্ত কলকারীকে Room.ClientId0 এর জন্য চেক করতে বাধ্য করবে :

var aRoom = new Room(aClient);
var clientId = aRoom.ClientId;
if (clientId == 0) RestartRoombookingWizard();
else ContinueRoombooking(clientid);

অদ্ভুত বাগগুলি অন্যান্য ডিভস (বা নিজেকে!) সাথে কিছু সময় "ত্রুটি কোড" রিটার্ন মানটি ভুলে যেতে ভুলে যেতে পারে।
এটি নিরাপদে চালান এবং দ্রুত ব্যর্থ হন। কলারটিকে আরও বেশি গণ্ডগোলের পরিবর্তে কল স্ট্যাকের উচ্চতর স্থানে নুলরেফারেক্সটেক্সেকশনটি নিক্ষেপ করার অনুমতি দিন এবং "করুণভাবে" এটিকে ধরুন ...

অন্য একটি নোটে, আপনি যদি প্রকাশ করতে আগ্রহী হন Clientএবং টেলডন্টআস্কClientId সম্পর্কেও ভাবেন । আপনি কী অর্জন করতে চান সেগুলি না বলার পরিবর্তে যদি আপনি কোনও জিনিস থেকে খুব বেশি জিজ্ঞাসা করেন তবে আপনি পরে একসাথে সমস্ত কিছু মিলিয়ে শেষ করতে পারেন, পরে পরিবর্তন আরও জটিল করে তোলা।


এটির NotSupportedExceptionঅপব্যবহার হচ্ছে, আপনার ArgumentNullExceptionপরিবর্তে এটি ব্যবহার করা উচিত ।
ফারাপ

1

সি # 6.0 হিসাবে, যা এখন প্রকাশিত হয়েছে, আপনার কেবল এটি করা উচিত,

public class Room
{
    public Room(Client client)
    {
        this.Client = client;
    }

    public Client Client { get; }
}

public class Client
{
    public Client(long id)
    {
        this.Id = id;
    }

    public long Id { get; }
}

একটি সম্পত্তি পালন Clientকরতে Roomএনক্যাপস্যুলেশন একজন সুস্পষ্ট লঙ্ঘন এবং শুষ্ক নীতি।

আপনি অ্যাক্সেস করার প্রয়োজন হলে Idএকটি এর Clientএকটি এর Roomআপনি কি করতে পারেন,

var clientId = room.Client?.Id;

উল্লেখ্য ব্যবহার নাল শর্তসাপেক্ষ অপারেটর , clientIdএকটি হতে হবে long?, যদি Clientহয় null, clientIdহতে হবে null, অন্যথায় clientIdমান থাকবে Client.Id


তবে এর clientidধরণটি কি দীর্ঘায়িত হয়?
মিশেল

@ মিশেল ভাল, যদি কোনও ঘরে কোনও ক্লায়েন্ট থাকতেই হয় তবে এটির জন্য শুল্ক পরীক্ষা করুন। তাহলে var clientId = room.Client.Idউভয়ই নিরাপদ এবং long
Jodrell
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.