একটি অ স্থির পদ্ধতিতে আমি ব্যবহার করতে পারি this.GetType()
এবং এটিটি ফিরে আসত Type
। Type
স্থির পদ্ধতিতে আমি কীভাবে এটি পেতে পারি ? অবশ্যই, আমি কেবল লিখতে পারি না typeof(ThisTypeName)
কারণ ThisTypeName
এটি কেবল রানটাইমে পরিচিত। ধন্যবাদ!
একটি অ স্থির পদ্ধতিতে আমি ব্যবহার করতে পারি this.GetType()
এবং এটিটি ফিরে আসত Type
। Type
স্থির পদ্ধতিতে আমি কীভাবে এটি পেতে পারি ? অবশ্যই, আমি কেবল লিখতে পারি না typeof(ThisTypeName)
কারণ ThisTypeName
এটি কেবল রানটাইমে পরিচিত। ধন্যবাদ!
উত্তর:
আপনি যদি this.GetType()
স্থির পদ্ধতির সমতুল্য 1 টি লাইনার সন্ধান করেন তবে নীচের চেষ্টা করুন।
Type t = MethodBase.GetCurrentMethod().DeclaringType
যদিও এটি সম্ভবত ব্যবহারের চেয়ে অনেক বেশি ব্যয়বহুল typeof(TheTypeName)
।
typeof(TheTypeName)
কোনও কিছুর কাছে স্থানান্তরিত হয় তবে ত্রুটিগুলি এড়ানো সহজ but
এমন কিছু আছে যা অন্যান্য উত্তরগুলি বেশ পরিষ্কারভাবে ব্যাখ্যা করতে পারে নি, এবং যা প্রকারের সময় কেবলমাত্র টাইপ পাওয়া যায় সে সম্পর্কে আপনার ধারণার সাথে প্রাসঙ্গিক।
আপনি যদি কোনও স্থিতিশীল সদস্যকে কার্যকর করতে কোনও ডাইরেক্টেড প্রকার ব্যবহার করেন তবে আসল টাইপের নাম বাইনারিটিতে বাদ দেওয়া হবে। সুতরাং উদাহরণস্বরূপ, এই কোডটি সংকলন করুন:
UnicodeEncoding.GetEncoding(0);
এখন এটিতে ইলডਜ਼ਮ ব্যবহার করুন ... আপনি দেখতে পাবেন যে কলটি এইভাবে নির্গত হয়েছিল:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
সংকলকটি কলটি সমাধান করেছে Encoding.GetEncoding
- UnicodeEncoding
বামের কোনও সন্ধান নেই । এটি আপনার "বর্তমান ধরণের" ধারণাটি অযৌক্তিক করে তোলে, আমি ভয় করি।
আরেকটি সমাধান হ'ল একটি স্বাবলম্বী প্রকার ব্যবহার করা
//My base class
//I add a type to my base class use that in the static method to check the type of the caller.
public class Parent<TSelfReferenceType>
{
public static Type GetType()
{
return typeof(TSelfReferenceType);
}
}
তারপরে যে বর্গটি উত্তরাধিকারসূত্রে আসে, আমি স্ব-রেফারেন্সিং টাইপটি তৈরি করি:
public class Child: Parent<Child>
{
}
এখন প্যারেন্টের অভ্যন্তরে কল টাইপ অফ (টিএসএলএফআরফারেন্সটাইপ) কলকারীর প্রকারটি পাবেন এবং কোনও উদাহরণের প্রয়োজন ছাড়াই কল করুন return
Child.GetType();
-রব
আপনি this
একটি স্থিতিশীল পদ্ধতিতে ব্যবহার করতে পারবেন না , সুতরাং এটি সরাসরি সম্ভব নয়। যাইহোক, যদি আপনার কোনও বস্তুর প্রকারের প্রয়োজন হয় তবে কেবল GetType
এটির কল করুন এবং this
উদাহরণটি আপনাকে একটি প্যারামিটার তৈরি করুন , যেমন:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
যদিও এটি একটি দুর্বল নকশার মতো মনে হচ্ছে। আপনি কি নিশ্চিত যে আপনার নিজের স্ট্যাটিক পদ্ধতির অভ্যন্তরে উদাহরণটির ধরণটি সত্যই পাওয়া দরকার? মনে হচ্ছে একটু উদ্ভট। কেন শুধু একটি উদাহরণ পদ্ধতি ব্যবহার করবেন না?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
আপনি কেন টাইপফ (এই টাইপনাম) ব্যবহার করতে পারবেন না তা আমি বুঝতে পারি না। যদি এটি একটি জেনেরিক প্রকারের হয় তবে এটি ব্যবহার করা উচিত:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
এটি যদি জেনেরিক ধরণের হয় তবে:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
আমি কি এখানে স্পষ্ট কিছু মিস করছি?
যখন আপনার সদস্য অবিচল থাকে, আপনি সর্বদা জানবেন যে রানটাইমের সময় এটি কোন ধরণের অংশ। এক্ষেত্রে:
class A
{
public static int GetInt(){}
}
class B : A {}
আপনি কল করতে পারবেন না (সম্পাদনা করুন: আপাতদৃষ্টিতে, আপনি নীচের মন্তব্য দেখতে পারেন, তবে আপনি এখনও এ-তে কল করবেন):
B.GetInt();
সদস্য অবিচলিত হওয়ার কারণে এটি উত্তরাধিকারের পরিস্থিতিতে অংশ নেয় না। কিন্তু, আপনি সর্বদা জানেন যে টাইপটি এ।
আমার উদ্দেশ্যে, আমি @ টি-মোটির ধারণা পছন্দ করি। যদিও আমি বছরের পর বছর ধরে "স্ব-রেফারেন্সিং ধরণের" তথ্য ব্যবহার করেছি, বেস ক্লাসের রেফারেন্স পরে করা আরও কঠিন।
উদাহরণস্বরূপ (উপরে থেকে @ রব লেক্লার্ক উদাহরণ ব্যবহার করে):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
এই নিদর্শনটির সাথে কাজ করা চ্যালেঞ্জিং হতে পারে, উদাহরণস্বরূপ; কোনও ফাংশন কল থেকে আপনি বেস ক্লাসটি কীভাবে ফিরে পাবেন?
public Parent<???> GetParent() {}
বা টাইপ কাস্টিং যখন?
var c = (Parent<???>) GetSomeParent();
সুতরাং, আমি যখন পারি তখন এটি এড়াতে চেষ্টা করি এবং যখন প্রয়োজন তখন এটি ব্যবহার করি। যদি আপনার অবশ্যই হয় তবে আমি আপনাকে এই প্যাটার্নটি অনুসরণ করার পরামর্শ দিচ্ছি:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
এখন আপনি (আরও) সহজেই এর সাথে কাজ করতে পারেন BaseClass
। যাইহোক, আমার বর্তমান পরিস্থিতিটির মতো সময় রয়েছে, যেখানে বেস বর্গের মধ্যে থেকে উত্পন্ন শ্রেণীর প্রকাশ করা প্রয়োজন হয় না এবং @ এম-মোতির পরামর্শটি ব্যবহার করা সঠিক পন্থা হতে পারে।
যাইহোক, @ এম-মোটির কোড ব্যবহার করা ততক্ষণ কাজ করবে যতক্ষণ না বেস ক্লাসে কল স্ট্যাকের কোনও ইনস্ট্যান্স কনস্ট্রাক্টর না থাকে। দুর্ভাগ্যক্রমে আমার বেস ক্লাসগুলি উদাহরণ নির্মাণকারী ব্যবহার করে।
অতএব, এখানে আমার বর্ধিত পদ্ধতিটি অ্যাকাউন্ট বেস শ্রেণীর 'উদাহরণস্বরূপ' নির্মাতাদের গ্রহণ করে:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}
সম্পাদনা করুন এই পদ্ধতিগুলি কেবল তখনই কার্যকর হবে যখন আপনি পিডিবি ফাইলগুলি এক্সিকিউটেবল / লাইব্রেরির সাথে মার্কম্নল হিসাবে স্থাপন করবেন আমার দিকে ইঙ্গিত ।
অন্যথায় এটি শনাক্ত করার জন্য একটি বিশাল সমস্যা হবে: বিকাশে ভাল কাজ করে, তবে সম্ভবত উত্পাদন হয় না।
ইউটিলিটি পদ্ধতি, আপনার কোডের প্রতিটি জায়গা থেকে আপনার প্রয়োজন হলে কেবল পদ্ধতিটি কল করুন:
public static Type GetType()
{
var stack = new System.Diagnostics.StackTrace();
if (stack.FrameCount < 2)
return null;
return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType;
}