জেনেরিক শ্রেণির স্থির সদস্যরা কি নির্দিষ্ট দৃষ্টিতে আবদ্ধ?


85

এটি একটি বাস্তব প্রশ্নের চেয়ে একটি ডকুমেন্টেশন বেশি। এটি এখনও এসও তে সম্বোধন করা হয়নি বলে মনে হয় না (যদি না আমি এটি মিস করি), সুতরাং এখানে যায়:

একটি জেনেরিক শ্রেণীর কল্পনা করুন যাতে স্থির সদস্য রয়েছে:

class Foo<T> {
    public static int member;
}

প্রতিটি নির্দিষ্ট শ্রেণীর জন্য সদস্যের নতুন কোনও উদাহরণ রয়েছে, বা সমস্ত ফু-টাইপ শ্রেণীর জন্য কেবল একটি একক উদাহরণ রয়েছে?

এটি সহজে কোডের মাধ্যমে এটি যাচাই করা যেতে পারে:

Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);

ফলাফল কী এবং এই আচরণের নথিটি কোথায়?


4
সংক্ষিপ্ত উত্তর: প্রতিটি প্রকৃত শ্রেণীর জন্য একটি নতুন উদাহরণ রয়েছে , অর্থাত Tব্যবহৃত প্রতিটি প্রকারের জন্য একটি ( Foo<int>এবং Foo<string>দুটি পৃথক শ্রেণীর প্রতিনিধিত্ব করে, এবং প্রতিটি ক্ষেত্রে একটি উদাহরণ থাকবে, তবে এর কয়েকটি Foo<int>উদাহরণ একক উদাহরণ ভাগ করবে member)। আরও বিশদ উদাহরণের জন্য দেখুন: stackoverflow.com/a/38369256/336648
Kjartan

উত্তর:


92

একটি staticক্ষেত্র সমস্ত উদাহরণ জুড়ে ভাগ করা হয় একই ধরনেরFoo<int>এবং Foo<string>দুটি ভিন্ন ধরণের। নিম্নলিখিত কোডের লাইন দ্বারা এটি প্রমাণিত হতে পারে:

// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));

যেখানে এটি নথিভুক্ত করা হয়েছে, নিম্নলিখিতটি সি # ভাষা নির্দিষ্টকরণের (সি # 3 এর জন্য) বিভাগের 1.6.5 বিভাগে পাওয়া গেছে :

একটি স্থিতিশীল ক্ষেত্র ঠিক একটি স্টোরেজ অবস্থান সনাক্ত করে location শ্রেণীর কতগুলি উদাহরণ তৈরি করা হয় তা বিবেচনা না করেই স্থির ক্ষেত্রের কেবলমাত্র একটি অনুলিপি থাকে।

যেমন আগে বলা হয়েছে; Foo<int>এবং Foo<string>একই বর্গ নয়; তারা একই জেনেরিক শ্রেণি থেকে নির্মিত দুটি ভিন্ন শ্রেণি। কীভাবে এটি ঘটে তা উপরোক্ত দলিলের ৪.৪ বিভাগে বর্ণিত:

একটি জেনেরিক ধরণের ঘোষণাপত্র, নিজেই, একটি আনবাউন্ড জেনেরিক প্রকারকে বোঝায় যা ধরণের আর্গুমেন্ট প্রয়োগের মাধ্যমে বিভিন্ন ধরণের তৈরি করতে "ব্লুপ্রিন্ট" হিসাবে ব্যবহৃত হয়।


26
আপনি যদি সি # এবং জাভা উভয় ক্ষেত্রে বিকাশ করেন তবে এখানে একটি গ্যাচা রয়েছে। সি # তে বিভিন্ন ধরণের Foo<int>এবং যদিও জাভা জেনেরিকের সাথে টাইপ করে (টাইপ ইরেজর / কম্পাইলার ট্রিকস) জাভা একই ধরণের। Foo<String>
পাওয়ারলর্ড

যদি এটি হয় তবে কী হবে: ফু <int> foo1 = নতুন ফু <int> (); foo1.member = 10; ফু <int> foo2 = নতুন ফু <int> (); foo2.member = 20; এখানে কি হয়?
সবাই

@ প্রত্যেকের সদস্যের মান উভয় ক্ষেত্রেই পরিবর্তিত হবে (এবং 20 হবে) কারণ তারা একই ধরণের ফু <int> ভাগ করে নেয়।
স্টাস ইভানভ

4
আপনি যদি কোনও অ-জেনেরিক বেস ক্লাসের উত্তরাধিকারী হন, যার স্থিতিশীল সদস্য রয়েছে উত্পন্ন জেনেরিক শ্রেণিতে? এটি কি এখনও সত্য হবে?
Brain2000

@StasIvanov, foo1.member 10 থাকবে এবং foo2.member হতে হবে 20 যাচাই করুন
SHRI

16

এখানে সমস্যাটি আসলে "জেনেরিক ক্লাস" মোটেই ক্লাস নয় এটাই সত্য।

জেনেরিক বর্গ সংজ্ঞাগুলি ক্লাসগুলির জন্য কেবলমাত্র টেম্পলেট এবং তাদের ধরণের পরামিতি নির্দিষ্ট না করা পর্যন্ত এগুলি কেবলমাত্র টুকরো টুকরো (বা কয়েকটি মুখ্য বাইট)।

রানটাইমের সময়, কেউ এই টেমপ্লেটের জন্য একটি প্রকারের প্যারামিটার নির্দিষ্ট করতে পারে, এটি এটিকে প্রাণবন্ত করে তোলে এবং এখন পুরোপুরি নির্দিষ্ট টাইপের একটি শ্রেণি তৈরি করে। এজন্য স্থির বৈশিষ্ট্যগুলি টেম্পলেট-বিস্তৃত নয় এবং এজন্যই আপনি List<string>এবং এর মধ্যে কাস্ট করতে পারবেন না List<int>

সেই সম্পর্কটি ক্লাস-অবজেক্টের সম্পর্ককে আয়না দেয়। ক্লাস যেমন অস্তিত্ব নেই * যতক্ষণ না আপনি সেগুলি থেকে কোনও বস্তু ইনস্ট্যান্ট করেন, জেনেরিক ক্লাসগুলির অস্তিত্ব থাকে না, যতক্ষণ না আপনি টেমপ্লেটের উপর ভিত্তি করে কোনও ক্লাস তৈরি করেন।

পিএস এটি ঘোষণা করা বেশ সম্ভব

class Foo<T> {
    public static T Member;
}

এ থেকে স্পষ্টতই স্পষ্ট যে স্থির সদস্যদের ভাগ করা যায় না, কারণ টি বিভিন্ন বিশেষত্বের জন্য আলাদা।


4

তারা ভাগ করা হয় না। এটি কোথায় দলিলযুক্ত তা নিশ্চিত নয় তবে বিশ্লেষণ সতর্কতা CA1000 ( জেনেরিক ধরণের স্থির সদস্যদের ঘোষণা করবেন না) কোডটিকে আরও জটিল করার ঝুঁকির কারণে কেবল এই বিরুদ্ধে সতর্ক করে।


4
বাহ, আর একটি নিয়ম আমি এফএক্স কপ-এর সাথে মিলিত হব না।
ম্যাথু হোয়াইট


3

সি # জেনেরিকের প্রয়োগ সি ++ এর আরও বেশি কাছাকাছি। এই দুটি ভাষায় MyClass<Foo>এবং MyClass<Bar>স্থির সদস্যদের ভাগ করবেন না তবে জাভাতে তারা করেন। সি # এবং সি ++ তে MyClass<Foo>অভ্যন্তরীণভাবে সংকলনের সময় সম্পূর্ণ নতুন ধরণের তৈরি হয় যেন জেনেরিকগুলি ম্যাক্রোর মতো। আপনি সাধারণত তাদের উত্পাদিত নামগুলি স্ট্যাক ট্রেস, লাইক MyClass'1এবং এ দেখতে পারেন MyClass'2। এ কারণেই তারা স্থির ভেরিয়েবলগুলি ভাগ করে না। জাভাতে, জেনেরিকগুলি নন-জেনেরিক প্রকারগুলি ব্যবহার করে কোডার জেনারেট করার আরও সহজ পদ্ধতি দ্বারা প্রয়োগ করা হয় এবং পুরোপুরি টাইপ কাস্ট যুক্ত করা হয়। সুতরাং MyClass<Foo>এবং MyClass<Bar>জাভাতে সম্পূর্ণ দুটি নতুন ক্লাস তৈরি করবেন না, পরিবর্তে তারা উভয়ই একই বর্গের MyClassনীচে এবং সে কারণেই তারা স্থিতিশীল ভেরিয়েবলগুলি ভাগ করে।


1

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

তবে যেহেতু ফু <<> ফু <স্ট্রিং> এর একই শ্রেণি নয় তবে এই দুটি সংখ্যা ভাগ করা নেই।

এটি দেখানোর জন্য একটি উদাহরণ:

TestClass<string>.Number = 5;
TestClass<int>.Number = 3;

Console.WriteLine(TestClass<string>.Number);  //prints 5
Console.WriteLine(TestClass<int>.Number);     //prints 3

-4

আইএমও, আপনার এটি পরীক্ষা করা দরকার, তবে আমি এটি মনে করি

Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);

আউটপুট আসবে 1কারণ আমি মনে করি যে সংকলনের সময়, সংকলকটি আপনার ব্যবহৃত প্রতিটি জেনেরিক শ্রেণির জন্য 1 শ্রেণি তৈরি করে (আপনার উদাহরণে: Foo<int>এবং Foo<string>)।

তবে আমি 100% নিশ্চিত নই =)।

মন্তব্য: আমি মনে করি যে এ জাতীয় স্ট্যাটিক বৈশিষ্ট্যগুলি ব্যবহার করা ভাল নকশা বা একটি ভাল অনুশীলন নয়।


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