সি # জেনারিকসে "ডিফল্ট" ধরণের পরামিতিগুলির জন্য কি যুক্তিসঙ্গত দৃষ্টিভঙ্গি রয়েছে?


93

সি ++ টেম্পলেটগুলিতে, একটি নির্দিষ্ট ধরণের পরামিতি একটি ডিফল্ট বলে নির্দিষ্ট করতে পারে। অর্থাৎ স্পষ্টভাবে নির্দিষ্ট না করা হলে এটি টাইপ টি ব্যবহার করবে

এটি সি # তে করা বা আনুমানিক করা যেতে পারে?

আমি এরকম কিছু খুঁজছি:

public class MyTemplate<T1, T2=string> {}

যাতে প্রকারের একটি উদাহরণ যা স্পষ্টভাবে নির্দিষ্ট করে না T2:

MyTemplate<int> t = new MyTemplate<int>();

মূলত হবে:

MyTemplate<int, string> t = new MyTemplate<int, string>();

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


আমি মনে করি যে ফ্যাক্টরি ম্যাথস প্যাটার্ন আমি উত্তর দিয়েছি তা আপনার পরিস্থিতিতে ভাল। একমাত্র ত্রুটিটি হ'ল আপনার সরাসরি নির্মাণকারী ব্যবহারের পরিবর্তে স্থির কারখানা পদ্ধতিগুলির মাধ্যমে অবজেক্টগুলি ইনস্ট্যান্ট করা দরকার। তবে এই সমাধানটি আপনাকে দুটি পরিবর্তে কেবল একটি ক্লাসে নিয়ে যায়।
থানাসিস ইওনানিডিস

উত্তর:


77

সাবক্লাসিং সেরা বিকল্প।

আমি আপনার মূল জেনেরিক ক্লাস সাবক্লাস করব:

class BaseGeneric<T,U>

একটি নির্দিষ্ট বর্গ সঙ্গে

class MyGeneric<T> : BaseGeneric<T, string>

এটি আপনার যুক্তিগুলিকে এক জায়গায় রাখা (বেস ক্লাস) রাখা সহজ করে তোলে, তবে উভয় ব্যবহারের বিকল্প সরবরাহ করাও সহজ। শ্রেণীর উপর নির্ভর করে, এটি ঘটতে সম্ভবত খুব কম অতিরিক্ত কাজ প্রয়োজন।


4
আহ ... যে বোধগম্য হয়। প্রকারের পরামিতিগুলি একটি স্বতন্ত্র স্বাক্ষর সরবরাহ করে যদি প্রকারের নামটি কি একই হতে দেওয়া হয়?
el2iot2

4
@ আই: হ্যাঁ, জেনেরিকগুলি overloadableপ্যারামিটার গণনা দ্বারা হয়।
এমএমএক্স

@ জি: হ্যাঁ, তবে আমি তা থেকে সতর্ক থাকব। এটি করা। নেট এ "আইনী" তবে এটি বিভ্রান্তির কারণ হতে পারে। আমি বরং স্ট্রিং উত্সযুক্ত টাইপের নামটি মূল জেনেরিক শ্রেণীর সাথে সমান হতে চাই (তাই এটি কী / এটি সহজেই খুঁজে পাওয়া সহজ) তবে এমন একটি নাম যা এটি স্পষ্ট করে তোলে যে এটি একটি স্ট্রিং।
রিড কোপসি

@ রিড: এটি কি আসলেই বিভ্রান্তির দিকে পরিচালিত করে? এই নির্দিষ্ট ক্ষেত্রে, আমি মনে করি একই নামটি এমনকি এমনকি সহায়তা করে। .NET এ উদাহরণ রয়েছে যা একই কাজ করে: উদাহরণস্বরূপ Func <> প্রতিনিধি।
এমএমএক্স

4
উদাহরণস্বরূপ, ভবিষ্যদ্বাণী করা <T> হ'ল ফানক <টি, বুল>, তবে এটির একটি নতুন উদ্দেশ্যে নামকরণ করা হয়েছে।
রিড কোপসি

20

একটি সমাধান সাবক্লাসিং হয়। পরিবর্তে আমি যেটি ব্যবহার করব তা হ'ল কারখানার পদ্ধতিগুলি (ভের কীওয়ার্ডের সাথে মিলিত)।

public class MyTemplate<T1,T2>
{
     public MyTemplate(..args..) { ... } // constructor
}

public static class MyTemplate{

     public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
     {
         return new MyTemplate<T1, T2>(... params ...);
     }

     public static MyTemplate<T1, string> Create<T1>(...args...)
     {
         return new MyTemplate<T1, string>(... params ...);
     }
}

var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();

উপরের উদাহরণে val2টাইপ হয় MyTemplate<int,string> এবং এটি থেকে প্রাপ্ত কোনও প্রকার নয়।

একটি টাইপ class MyStringTemplate<T>:MyTemplate<T,string>হিসাবে একই ধরণের হয় না MyTemplate<T,string>। এটি নির্দিষ্ট পরিস্থিতিতে কিছু সমস্যা তৈরি করতে পারে। উদাহরণ হিসেবে বলা যায় তোমাদের মধ্যে একটি দৃষ্টান্ত নিক্ষেপ করতে পারবে না MyTemplate<T,string>করতে MyStringTemplate<T>


4
এটি সর্বাধিক ব্যবহারযোগ্য পন্থা। খুব সুন্দর সমাধান
টি-মোটি

12

আপনি যেমন ওভারলোড একটি বর্গ তৈরি করতে পারেন

public class MyTemplate<T1, T2> {
    public T1 Prop1 { get; set; }
    public T2 Prop2 { get; set; }
}

public class MyTemplate<T1> : MyTemplate<T1, string>{}

দেরী উত্তর পোস্ট করার আগে দয়া করে অন্যান্য উত্তরগুলি পড়ুন, কারণ সম্ভবত আপনার সমাধানটি অন্যদের মতো।
চেং চেন

7
গৃহীত উত্তরটি বিভিন্ন নামের সাথে একটি শ্রেণি তৈরি করছিল, আমার সমাধানটি একই ক্লাসের
ওভারলোডিং

4
না, দুজনেই একটি নতুন ক্লাস তৈরি করছে। নামটি এখানে গুরুত্বপূর্ণ নয়। না MyTemplate<T1>থেকে একটি পৃথক শ্রেণি । MyTemplate<T1, T2>AnotherTemplate<T1>
চেং চেন

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

4
দুর্ভাগ্যক্রমে এই সমাধানটি এখনও সত্য "ডিফল্ট" জেনেরিক আর্গুমেন্টের চেয়ে নিকৃষ্ট, কারণ একটিকে MyTemplate<T1, string>বরাদ্দ করা যায় না MyTemplate<T1>, যা ইচ্ছা হতে পারে
ফেলক

10

সি # এই জাতীয় বৈশিষ্ট্য সমর্থন করে না।

যেমনটি আপনি বলেছেন, আপনি এটি সাবক্লাস করতে পারেন (যদি এটি সিল না করা হয়, এবং সমস্ত নির্মাণকারীর ঘোষণার সদৃশ করুন) তবে এটি সম্পূর্ণ আলাদা জিনিস।


3

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


4
আসলে তা না. এটি কোনও অ্যাট্রিবিউট (VB.NET- এ ডিফল্ট প্যারামিটারের মতো) দিয়ে সম্পন্ন করা যেতে পারে এবং সংকলকটি সংকলনের সময়ে সংকলকটি এটি প্রতিস্থাপন করতে পারে। প্রাথমিক কারণ হ'ল সি # ডিজাইন লক্ষ্য।
এমএমএক্স

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

@ অ্যান্ড্রু, ডিফল্ট প্যারামিটারটি জেনেরিক সীমাবদ্ধতার দরকার নেই। এটি যদি সি ++ তে ডিফল্ট টেম্পলেট প্যারামিটারগুলির মতো আচরণ করে তবে অটোমেটোনিকের ক্লাসের উপর প্রসারিত করা এটি পুরোপুরি ভাল হবে: মাই টেম্পলেট <<, ফ্লোট> x = নাল কারণ টি 2 এর কোনও জেনেরিক বাধা নেই, তাই ডিফল্ট স্ট্রিংয়ের ডিফল্ট সত্ত্বেও ফ্লোট ঠিক আছে । এইভাবে ডিফল্ট টেম্পলেট প্যারামিটারগুলি মূলত MyTemplate <int> মাইটিম্প্লেট <int, স্ট্রিং> এর শর্টহ্যান্ড হিসাবে লেখার জন্য কেবল "সিনট্যাকটিকাল চিনি"।
টাইলার

@ অ্যান্ড্রু, আমি সম্মত হই যে সি # সংকলকটি যাচাই করা উচিত যে এই জাতীয় ডিফল্ট টেম্পলেট প্যারামিটারগুলি বিদ্যমান জেনেরিক কনসেন্টেটগুলি সন্তুষ্ট করে। সি # সংকলক ইতিমধ্যে শ্রেণীর ঘোষণার ক্ষেত্রে কিছু একই জিনিস যাচাই করেছে, উদাহরণস্বরূপ একটি জেনেরিক সীমাবদ্ধতা যুক্ত করুন যেমন "যেখানে ইউ: ইসোমেন্টারফেস" রিডের বেসজেনারিক <টি, ইউ> শ্রেণিতে এবং তারপরে মাইজেনেরিক <টি> একটি ত্রুটি সহ সংকলন করতে ব্যর্থ হবে। একটি ডিফল্ট টেম্পলেট প্যারামিটার যাচাই করা অনেকটাই একই রকম হবে: সংকলক একটি শ্রেণীর ঘোষণার সাথে যাচাই করে এবং ত্রুটি বার্তাটি একই বা খুব অনুরূপ হতে পারে।
টাইলার

"এটি প্রয়োগ করা একটি কঠিন বৈশিষ্ট্য হবে" এটি বোকামি। এটি প্রয়োগ করা তুচ্ছ হবে। টেমপ্লেটের সীমাবদ্ধতার বিরুদ্ধে কোনও ধরণের বৈধতা দেওয়ার কাজটি শক্ত হয় না কারণ প্রার্থীর ধরণটি ফাইলের আলাদা জায়গায় উপস্থিত হয় (যেমন টেমপ্লেটে টেমপ্লেটে ইনস্ট্যান্টেশনের পরিবর্তে)।
মাটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.