আমার সুস্পষ্ট কাস্টিং অপারেটরের ব্যবহার কি যুক্তিসঙ্গত বা খারাপ হ্যাক?


24

আমার একটি বড় অবজেক্ট রয়েছে:

class BigObject{
    public int Id {get;set;}
    public string FieldA {get;set;}
    // ...
    public string FieldZ {get;set;}
}

এবং একটি বিশেষজ্ঞ, ডিটিও-এর মতো অবজেক্ট:

class SmallObject{
    public int Id {get;set;}
    public EnumType Type {get;set;}
    public string FieldC {get;set;}
    public string FieldN {get;set;}
}

আমি ব্যক্তিগতভাবে স্পষ্টভাবে বিগঅবজেক্টকে স্মলবজেক্টে কাস্ট করার ধারণা পেয়েছি - এটি একতরফা, ডেটা-হারাতে যাওয়া অপারেশন - তা খুব স্বজ্ঞাত এবং পাঠযোগ্য knowing

var small = (SmallObject) bigOne;
passSmallObjectToSomeone(small);

এটি সুস্পষ্ট অপারেটর ব্যবহার করে প্রয়োগ করা হয়েছে:

public static explicit operator SmallObject(BigObject big){
    return new SmallObject{
        Id = big.Id,
        FieldC = big.FieldC,
        FieldN = big.FieldN,
        EnumType = MyEnum.BigObjectSpecific
    };
}

এখন, আমি পদ্ধতি SmallObjectFactoryসহ একটি ক্লাস তৈরি FromBigObject(BigObject big)করতে পারি, এটি একই কাজ করবে, এটি নির্ভরতা ইনজেকশনে যুক্ত করতে এবং যখন প্রয়োজন হবে তখন এটি কল করবে ... তবে আমার কাছে এটি আরও বেশি জটিল এবং অপ্রয়োজনীয় বলে মনে হয়।

পিএস আমি নিশ্চিত নই যে এটি প্রাসঙ্গিক কিনা, তবে এমন কিছু থাকবে OtherBigObjectযা রূপান্তরিত করতে সক্ষম হবে SmallObject, আলাদা করে সেট করে EnumType


4
কেন কনস্ট্রাক্টর নয়?
edc65

2
নাকি স্ট্যাটিক কারখানা পদ্ধতি?
ব্রায়ান গর্ডন

আপনার কেন কারখানার ক্লাস, বা নির্ভরতা ইনজেকশন লাগবে? আপনি সেখানে একটি মিথ্যা দ্বৈতত্ত্ব তৈরি করেছেন।
ব্যবহারকারী 253751

1
@ এমমিবিস - কারণ @ টেলাস্টিন প্রস্তাবিত .ToSmallObject()পদ্ধতি : (বা GetSmallObject()) সম্পর্কে আমি কোনওভাবেই ভাবি নি । একটি ক্ষণিকের কারণটি - আমি জানতাম আমার চিন্তাভাবনায় কিছু ভুল আছে, তাই আমি আপনাকে বলছি :)
জেরিনো

3
এটি ইসমলওবজেক্ট ইন্টারফেসের জন্য উপযুক্ত ব্যবহারের মতো বলে মনে হচ্ছে যা বিগবজেক্ট তার বিস্তৃত ডেটা / আচরণের একটি সীমিত সেটকে অ্যাক্সেস সরবরাহ করার উপায় হিসাবে প্রয়োগ করেছে। বিশেষত @ টেলাস্টিনের কোনও ToSmallObjectপদ্ধতির ধারণার সাথে একত্রিত হলে ।
মার্জন ভেনেমা

উত্তর:


0

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


এটি একটি ভয়ঙ্কর ধারণা। আমার ইতিমধ্যে জায়গায় অটোম্যাপার রয়েছে, সুতরাং এটি বাতাসের মতো হবে। এটির সাথে কেবল আমার ইস্যু রয়েছে: বিগঅজেক্ট এবং স্মলঅবজেক্ট কোনওভাবে সম্পর্কিত হওয়ার কোনও ট্রেস থাকা উচিত নয়?
গেরিনো

1
না আমি ম্যাপিং পরিষেবাটি বাদে আরও বিগবজেক্ট এবং স্মলবজেক্টকে মিলিয়ে কোনও সুবিধা দেখছি না।
এসবেন স্কভ পেডারসেন

7
সত্যি? একটি স্বয়ংচালক ডিজাইন সমস্যার জন্য আপনার সমাধান?
টেলাস্টিন

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

2
@ এসবেনসকভ পিডারসন এই সমাধানটি আপনার মেইলবক্সটি ইনস্টল করার জন্য একটি গর্ত খননের জন্য বুলডোজার ব্যবহার করার মতো। ভাগ্যক্রমে ওপি ইয়ার্ডটি যেভাবেই খনন করতে চেয়েছিল, তাই কোনও বুলডোজার এই ক্ষেত্রে কাজ করে। তবে, আমি সাধারণভাবে এই সমাধানটি সুপারিশ করব না ।
নীল

81

এটা ... দুর্দান্ত না। আমি কোডের সাথে কাজ করেছি যা এই চতুর কৌশলটি করেছে এবং এটি বিভ্রান্তির দিকে পরিচালিত করেছে। সর্বোপরি, আপনি যদি প্রত্যাশাগুলি কাস্ট করার জন্য পর্যাপ্ত পরিমাণের সাথে সম্পর্কিত থাকেন তবে কেবলমাত্র BigObjectএকটি SmallObjectভেরিয়েবলের জন্য বরাদ্দ করতে সক্ষম হবেন বলে আপনি আশা করবেন। যদিও এটি কার্যকর হয় না - আপনি টাইপ সিস্টেম সম্পর্কিত যতদূর চেষ্টা করে চেষ্টা করুন তবে সংকলক ত্রুটিগুলি পেয়ে যান, তারা সম্পর্কিত না re কাস্টিং অপারেটরের পক্ষে নতুন নতুন জিনিস তৈরি করাও হালকাভাবে বিরক্তিকর।

আমি .ToSmallObject()পরিবর্তে একটি পদ্ধতি সুপারিশ করব । এটি আসলে কী চলছে এবং ভার্বোজ হিসাবে এটি পরিষ্কার।


18
দোহ ... ToSmallObject () সবচেয়ে সুস্পষ্ট পছন্দ বলে মনে হচ্ছে। কখনও কখনও সর্বাধিক সুস্পষ্ট হ'ল সবচেয়ে অধরা;)
গেরিনো

6
mildly distastefulএকটি সংক্ষিপ্তসার এটি দুর্ভাগ্যজনক যে ভাষা এই ধরণের জিনিসটিকে টাইপকাস্টের মতো দেখতে দেয়। কেউই অনুমান করতে পারে না যে এগুলি সত্যিকারের অবজেক্ট ট্রান্সফর্মেশন যা তারা নিজেরাই না লিখে থাকে। এক-ব্যক্তি দলে, ঠিক আছে। যদি আপনি কারও সাথে সহযোগিতা করেন, সর্বোত্তম ক্ষেত্রে এটি সময় নষ্ট কারণ আপনাকে থামাতে হবে এবং এটি সত্যই অভিনেতা কিনা তা খুঁজে বের করতে হবে, বা যদি এটি সেই ক্রেজি রূপান্তরগুলির মধ্যে একটি হয়।
কেন্ট এ।

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

4
জন্য +1 .ToSmallObject()। অপারেটরদের আপনার ওভাররাইড খুব কমই করা উচিত।
ইতোলেদানো

6
@ ডরাস - কমপক্ষে নেট মধ্যে, Getবিদ্যমান জিনিস ফেরত বোঝায়। আপনি যদি না ছোট অবজেক্টে ক্রিয়াকলাপকে ওভাররাইড না করে থাকেন তবে দুটি Getকল অসম বস্তুগুলিতে ফিরে আসবে, এতে বিভ্রান্তি / বাগ / ডাব্লুটিএফস সৃষ্টি হবে।
টেলাস্টিন

11

আপনার দেখতে কেন প্রয়োজন হবে তা আমি দেখতে পাচ্ছি SmallObject, তবে আমি সমস্যার সাথে অন্যভাবে যোগাযোগ করব। ইস্যু এই ধরনের আমার পদ্ধতির একটি ব্যবহার করা ছদ্মরূপ । এর একমাত্র উদ্দেশ্য হ'ল এনক্যাপুলেট করা BigObjectএবং কেবলমাত্র নির্দিষ্ট সদস্যদের উপলব্ধ করা। এইভাবে, এটি একই উদাহরণে একটি নতুন ইন্টারফেস, এবং অনুলিপি নয়। অবশ্যই আপনি পারে এছাড়াও একটি কপি সঞ্চালন করতে চাই, কিন্তু আমি সুপারিশ করবে যে আপনি একটি পদ্ধতি ছদ্মরূপ (উদাহরণস্বরূপ সঙ্গে একযোগে যে উদ্দেশ্যে নির্মিত মাধ্যমে তা করতে return new SmallObject(instance.Clone()))।

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

দ্রষ্টব্য, এর অর্থ আশেপাশের অন্যান্য উপায়ের BigObjectউপর নির্ভর করে না SmallObject(এটি আমার নম্র মতামত হিসাবে হওয়া উচিত)।


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

@ ডোভাল আমি মনে করি এটিই মূল বিষয়। আপনি এটিকে কোনও নতুন শ্রেণিতে রূপান্তর করবেন না। আপনার যদি প্রয়োজন হয় তবে আপনি অন্য মুখোমুখি তৈরি করতে চাই। বিগঅবজেক্টে করা পরিবর্তনগুলি কেবল মুখের শ্রেণিতে প্রয়োগ করা হয় এবং এটি যেখানে ব্যবহৃত হয় সেখানে নয়।
নীল

এই পদ্ধতির এবং তেলস্তিনের উত্তরের মধ্যে একটি আকর্ষণীয় পার্থক্য হ'লSmallObject মিথ্যা উত্সাহিত করার দায়বদ্ধতা SmallObjectবা BigObject। ডিফল্টরূপে, এই পদ্ধতির SmallObjectব্যক্তিগত / সুরক্ষিত সদস্যদের উপর নির্ভরতা এড়াতে বাধ্য করে BigObject। আমরা আরও এক ধাপ এগিয়ে যেতে পারি এবং SmallObjectএকটি ToSmallObjectএক্সটেনশন পদ্ধতি ব্যবহার করে ব্যক্তিগত / সুরক্ষিত সদস্যদের উপর নির্ভরতা এড়াতে পারি ।
ব্রায়ান

@Brian আপনি ঝুঁকি cluttering BigObjectযে ভাবে। আপনি যদি অনুরূপ কিছু করতে চান তবে আপনি কি কোনও ToAnotherObjectসম্প্রসারণ পদ্ধতি তৈরি করতে চান BigObject? এগুলি BigObjectযেহেতু উদ্বেগের কারণ হওয়া উচিত নয় , সম্ভবত এটি এটি ইতিমধ্যে যথেষ্ট বড়। এটি আপনাকে BigObjectএর নির্ভরতা তৈরি থেকে পৃথক করার অনুমতি দেয় , এর অর্থ আপনি কারখানা এবং এ জাতীয় ব্যবহার করতে পারেন। অন্যান্য পদ্ধতির দৃ strongly়ভাবে দম্পতি BigObjectএবং SmallObject। এই বিশেষ ক্ষেত্রে এটি ঠিক হতে পারে, তবে আমার নম্র মতে এটি সর্বোত্তম অনুশীলন নয়।
নীল

1
@Neil বাস্তবিক, ব্রায়ান এটা ভুল ব্যাখ্যা, কিন্তু সে হল ডান - এক্সটেনশন পদ্ধতি সংযোজন পরিত্রাণ পেতে পারি। এটি আর BigObjectমিলিত হচ্ছে না SmallObject, এটি কোথাও কোথাও স্থির পদ্ধতি যা একটি যুক্তি নিয়ে BigObjectএবং ফিরে আসে SmallObject। প্রসারিত পদ্ধতিগুলি সত্যিকার অর্থে স্থির পদ্ধতিগুলিকে কল করার জন্য কেবল সিনট্যাকটিক চিনি। এক্সটেনশন পদ্ধতি নয় অংশ এর BigObject, এটি একটি সম্পূর্ণ পৃথক স্ট্যাটিক পদ্ধতি আছে। এটি আসলে এক্সটেনশন পদ্ধতিগুলির বেশ ভাল ব্যবহার এবং বিশেষত ডিটিও রূপান্তরগুলির জন্য খুব কার্যকর।
লুয়ান

6

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

আমি একটি প্রয়োজনীয়তা হিসাবে সুপারিশ করব যা x=(SomeType)foo;পরে কিছুক্ষণ পরে দেওয়া হয়েছিল y=(SomeType)foo;, উভয় জাতকে একই বস্তুতে প্রয়োগ করা হলে x.Equals(y)সর্বদা এবং চিরকাল সত্য হওয়া উচিত, এমনকি প্রশ্নে থাকা বস্তুটি দুটি বর্ণের মধ্যে পরিবর্তিত হয়েছিল। এ জাতীয় পরিস্থিতি যদি প্রয়োগ করতে পারে তবে উদাহরণস্বরূপ, একের মধ্যে বিভিন্ন ধরণের বস্তুর জুড়ি থাকে, যার মধ্যে প্রতিটি একে অপরের প্রতি অপরিবর্তনীয় রেফারেন্স রাখে এবং অন্যরকমের মধ্যে উভয়কেই বস্তু নিক্ষেপ করলে তার যুক্তটি ফিরে আসে। এটি এমন ধরণের ক্ষেত্রেও প্রযোজ্য যেগুলি পরিবর্তনযোগ্য বস্তুগুলিতে মোড়কের কাজ করে, তবে শর্ত থাকে যে মোড়কযুক্ত বস্তুর পরিচয় অপরিবর্তনীয় ছিল এবং একই ধরণের দুটি র‌্যাপার যদি তারা একই সংগ্রহটি মুড়ে ফেলে তবে তারা সমান হিসাবে প্রতিবেদন করবে।

আপনার নির্দিষ্ট উদাহরণটি পরিবর্তনীয় শ্রেণিগুলি ব্যবহার করে, তবে কোনওরূপে পরিচয় সংরক্ষণ করে না; এর মতো, আমি পরামর্শ দেব যে এটি কোনও ingালাই অপারেটরের উপযুক্ত ব্যবহার নয়।


1

এটা ঠিক আছে।

আপনার উদাহরণের সাথে সমস্যা হ'ল আপনি যেমন উদাহরণ-ইশ নাম ব্যবহার করেন। বিবেচনা:

SomeMethod(long longNum)
{
  int num = (int)longNum;
  /* ... */

এখন, আপনি যখন একটি ভাল ধারণা করেছি কি একটি দীর্ঘ এবং int- এ মানে, তারপর অন্তর্নিহিত ঢালাই উভয় intথেকে longথেকে স্পষ্ট ঢালাই longকরার intবেশ বোধগম্য হয়। এটা কিভাবে আরো বোধগম্য 3হয়ে 3এবং মাত্র এর সাথে কাজ করা আর উপায় নেই 3। এটি int.MaxValue + 1চেক করা প্রসঙ্গে কীভাবে এটি ব্যর্থ হবে তা বোধগম্য । এমনকি এটি কীভাবে int.MaxValue + 1একটি চেক না হওয়া প্রসঙ্গে ফলাফল হিসাবে int.MinValueকাজ করবে তা আঁকাবাঁকা করা খুব কঠিন কাজ নয়।

তেমনিভাবে, আপনি যখন বেইস টাইপটিতে স্পষ্টভাবে কাস্ট করেন বা কোনও উদ্ভূত প্রকারে স্পষ্টভাবে কাস্ট করেন তখন যে কেউ জানেন যে উত্তরাধিকার কীভাবে ঘটছে তা কার্যকর হয়, এবং ফলাফল কী হবে (বা কীভাবে এটি ব্যর্থ হতে পারে)।

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


প্রকৃতপক্ষে এগুলি প্রশ্নের মধ্যে যা সরবরাহ করা হয়েছে তার চেয়ে বেশি কিছু নয় - তবে উদাহরণস্বরূপ BigObjectএকটি বর্ণনা করতে পারে Employee {Name, Vacation Days, Bank details, Access to different building floors etc.}এবং SmallObjectহতে পারে একটি MoneyTransferRecepient {Name, Bank details}। থেকে একটি সরল অনুবাদ Employeeআছে MoneyTransferRecepient, এবং প্রয়োজনের চেয়ে আরও কোনও ডেটা ব্যাংকিং অ্যাপ্লিকেশনটিতে প্রেরণের কোনও কারণ নেই।
গেরিনো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.