জেনেরিক টাইপ প্যারামিটারে স্থির পদ্ধতি কল করা


107

আমি এই জাতীয় কিছু করার আশা করছিলাম তবে এটি সি # তে অবৈধ বলে মনে হচ্ছে:


public Collection MethodThatFetchesSomething<T>()
    where T : SomeBaseClass
{
    return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}

আমি একটি সংকলন-সময় ত্রুটি পেয়েছি: "'টি' একটি 'টাইপ প্যারামিটার', যা প্রদত্ত প্রসঙ্গে বৈধ নয়" "

জেনেরিক ধরণের প্যারামিটার দেওয়া, আমি কীভাবে জেনেরিক ক্লাসে একটি স্ট্যাটিক পদ্ধতি কল করতে পারি? স্থির পদ্ধতিটি সীমাবদ্ধতার ভিত্তিতে উপলব্ধ থাকতে হবে।


উত্তর:


58

এক্ষেত্রে আপনার কেবল সীমাবদ্ধ টাইপের স্থির পদ্ধতিটি সরাসরি কল করা উচিত। সি # (এবং সিএলআর) ভার্চুয়াল স্ট্যাটিক পদ্ধতি সমর্থন করে না। তাই:

T.StaticMethodOnSomeBaseClassThatReturnsCollection

... এর চেয়ে আলাদা হতে পারে না:

SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection

জেনেরিক প্রকারের প্যারামিটারের মধ্য দিয়ে যাওয়া একটি অবিবাহিত দিকনির্দেশনা এবং তাই এটি সমর্থিত নয়।


25
তবে আপনি যদি কোনও শিশু শ্রেণিতে আপনার স্থিতিশীল পদ্ধতিটি মাস্ক করেন? পাবলিক ক্লাস সোমারচিলড ক্লাস: সুমারবেসক্লাস {পাবলিক নতুন স্ট্যাটিক স্ট্যাটিকমেথডনসোমবেসক্লাসট্যাট রিটার্নস কালেকশন () {a জেনেরিক টাইপ থেকে স্ট্যাটিক পদ্ধতিতে অ্যাক্সেস পেতে আপনি কি কিছু করতে পারবেন?
হুগো ম্যাগেরন

2
জোশুয়া পেচের উত্তর নীচে দেখুন, আমি বিশ্বাস করি যে এই ক্ষেত্রে কাজ করবে।
রেমি ডেসপ্রেস-স্মিথ

1
চান return SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection();কাজ করে? যদি তা হয় তবে আপনার উত্তরটিতে এটি যুক্ত করতে পারেন। ধন্যবাদ। এটা আমার জন্য কাজ করে। আমার ক্ষেত্রে আমার ক্লাসে একটি টাইপ পরম ছিল তাই আমি করেছি return SomeBaseClass<T>.StaticMethodOnSomeBaseClassThatReturnsCollection();এবং এটি কাজ করে।
টুডমো

27

পূর্ববর্তী উত্তরটি বিস্তারিতভাবে বর্ণনা করার জন্য, আমি মনে করি যে আপনি এখানে যা চান তা প্রতিবিম্বের কাছাকাছি। আপনার কিছু করা উচিত বা করা উচিত নয় এর জন্য আমি 1001 কারণ দিতে পারলাম, আমি আপনার প্রশ্নের অনুরোধে উত্তর দেব। আমি মনে করি আপনার জেনেরিক প্যারামিটারের ধরণে getMethod পদ্ধতিটি কল করা উচিত এবং সেখান থেকে যাওয়া উচিত। উদাহরণস্বরূপ, একটি ফাংশনের জন্য:

public void doSomething<T>() where T : someParent
{
    List<T> items=(List<T>)typeof(T).GetMethod("fetchAll").Invoke(null,new object[]{});
    //do something with items
}

যেখানে টি এমন কোনও শ্রেণি যেখানে স্থির পদ্ধতি আনতে হবে সমস্ত ()।

হ্যাঁ, আমি জানি যে এটি ভয়াবহভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে যোগড়িয়ে না ঘুরিটে চালাতে না যেতে যেতে পারে এমন পিসিটেইনস) ভয়াবহভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে চলতে পারত না থেকে পিতামাতারা তার সমস্ত শিশু ক্লাসটি ফেচএল বাস্তবায়নের জন্য বাধ্য না করে তবে ক্র্যাশ হতে পারে তবে যেমনটি জিজ্ঞাসা করা হয়েছে তেমন প্রশ্নের উত্তর দেয়।


2
না কোনভাবেই না. জারেডপারটি একেবারে সঠিকভাবে পেয়েছে: টি স্ট্যাটিকমিথডঅনসোমবেসক্লাসট্যাট রিটার্নস সংকলন যেখানে টি: সামুব্যাসক্লাস কেবল কিছুটা বেসাসক্লাস.স্ট্যাটিক মেথডঅনসোমবেসক্লাসট্যাটার্ট্রান্সক্ল্যাশন সংগ্রহের তুলনায় আলাদা নয়।
রেমি ডেস্প্রেস-স্মিথ

2
এটি আমার প্রয়োজন ছিল এটি স্থির পদ্ধতিতে কাজ করে
মাইরো

এটি আমার প্রয়োজনীয় উত্তর ছিল কারণ আমার ক্লাস এবং বেস ক্লাসের নিয়ন্ত্রণ ছিল না।
টিম

8

এই জাতীয় পদ্ধতিটি কল করার একমাত্র উপায় প্রতিবিম্বের মাধ্যমে হবে, তবে, মনে হচ্ছে এটি একটি ইন্টারফেসে সেই কার্যকারিতাটি মোড়ানো এবং একটি উদাহরণ ভিত্তিক আইওসি / ফ্যাক্টরি / ইত্যাদি প্যাটার্ন ব্যবহার করা সম্ভব।


5

দেখে মনে হচ্ছে আপনি সি # তে কোনও "ভার্চুয়াল স্ট্যাটিক পদ্ধতি" নেই এই বিষয়টি ঘিরে কাজ করার জন্য জেনেরিকগুলি ব্যবহার করার চেষ্টা করছেন।

দুর্ভাগ্যক্রমে, এটি কাজ করবে না।


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

1
তাহলে কেন আপনি কেবল সামারবেসক্লাস.স্ট্যাটিকমিথড ... () কল করবেন না?
ব্র্যাড উইলসন

দুঃখিত, আমি আগের মন্তব্যে নিজেকে ভালভাবে ব্যাখ্যা করিনি। ফেচআল সমস্ত বেসে সংজ্ঞায়িত করা হয়, তবে উদ্ভূত শ্রেণিতে প্রয়োগ করা হয়। আমার এটি ডেরাইভেড ক্লাসে কল করা দরকার।
রেমি ডেসপ্রেস-স্মিথ

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

1
হ্যাঁ, আপনি ঠিক বলেছেন - আমি এখানে অবৈধ অনুমান করেছি। আলোচনার জন্য ধন্যবাদ, এটি আমাকে সঠিক পথে রাখতে সহায়তা করেছে।
রেমি ডেসপ্রেস-স্মিথ

2

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


1
সমস্যাটি হ'ল যেহেতু জেনেরিকগুলি রানটাইম দ্বারা সরবরাহ করা হয়, এর অর্থ সম্ভবত একটি নতুন সিএলআর সংস্করণ হবে - যা তারা (মূলত) 2.0 এর পরে এড়িয়ে চলেছে। হতে পারে আমরা একটি নতুন কারণ, যদিও ...
মার্ক গ্র্যাভেল

2

এখানে, আমি উদাহরণটি পোস্ট করি যে এটি কাজ করে, এটি একটি কর্মচঞ্চল

public interface eInterface {
    void MethodOnSomeBaseClassThatReturnsCollection();
}

public T:SomeBaseClass, eInterface {

   public void MethodOnSomeBaseClassThatReturnsCollection() 
   { StaticMethodOnSomeBaseClassThatReturnsCollection() }

}

public Collection MethodThatFetchesSomething<T>() where T : SomeBaseClass, eInterface
{ 
   return ((eInterface)(new T()).StaticMethodOnSomeBaseClassThatReturnsCollection();
}

2
এটি আমার জন্য একটি সিনট্যাক্স ত্রুটি দেয়? কী public T : SomeBaseClassমানে?
এরিক

যদি আপনার ক্লাসে উদাহরণ পদ্ধতি থাকে কিছু ইনস্ট্যান্সমেথড () আপনি সর্বদা এটি (নতুন টি ()) করে কল করতে পারেন some কিছু ইনসান্টস ম্যাথোড (); - তবে এটি একটি উদাহরণ পদ্ধতি কল করছে - শ্রেণিটির স্থির পদ্ধতিটি কীভাবে কল করতে হবে তা প্রশ্ন করা হয়েছিল।
টিমোথি

2

আমি কেবল এটি সেখানে ফেলে দিতে চেয়েছিলাম যে প্রসঙ্গের উপর নির্ভর করে কখনও কখনও প্রতিনিধিরা এই সমস্যাগুলি সমাধান করে।

যদি আপনাকে স্ট্যাটিক পদ্ধতিটি কোনও ধরণের কারখানা বা সূচনা পদ্ধতি হিসাবে কল করতে হয়, তবে আপনি কোনও প্রতিনিধি ঘোষণা করতে পারেন এবং স্থির পদ্ধতিটিকে প্রাসঙ্গিক জেনেরিক কারখানায় বা যা কিছু প্রয়োজন তার "এই স্ট্যাটিক পদ্ধতিযুক্ত জেনেরিক শ্রেণি" সরবরাহ করতে পারেন।

উদাহরণ স্বরূপ:

class Factory<TProduct> where TProduct : new()
{
    public delegate void ProductInitializationMethod(TProduct newProduct);


    private ProductInitializationMethod m_ProductInitializationMethod;


    public Factory(ProductInitializationMethod p_ProductInitializationMethod)
    {
        m_ProductInitializationMethod = p_ProductInitializationMethod;
    }

    public TProduct CreateProduct()
    {
        var prod = new TProduct();
        m_ProductInitializationMethod(prod);
        return prod;
    }
}

class ProductA
{
    public static void InitializeProduct(ProductA newProduct)
    {
        // .. Do something with a new ProductA
    }
}

class ProductB
{
    public static void InitializeProduct(ProductB newProduct)
    {
        // .. Do something with a new ProductA
    }
}

class GenericAndDelegateTest
{
    public static void Main()
    {
        var factoryA = new Factory<ProductA>(ProductA.InitializeProduct);
        var factoryB = new Factory<ProductB>(ProductB.InitializeProduct);

        ProductA prodA = factoryA.CreateProduct();
        ProductB prodB = factoryB.CreateProduct();
    }
}

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

এই পদ্ধতির কিছু উপকারিতাও রয়েছে, যেমন আপনি আর ডি পদ্ধতিগুলি পুনরায় ব্যবহার করতে পারেন, সেগুলি উদাহরণ পদ্ধতি ইত্যাদি হতে পারে etc.


1

এখানে বর্ণিত হিসাবে প্রতিবিম্ব ব্যবহার করে আপনি এটি করতে সক্ষম হবেন

লিঙ্কটি মারা যাওয়ার কারণে, আমি ওয়েবব্যাক মেশিনে সম্পর্কিত বিশদগুলি পেয়েছি:

ধরুন আপনার স্ট্যাটিক জেনেরিক পদ্ধতি সহ একটি ক্লাস রয়েছে:

class ClassWithGenericStaticMethod
{
    public static void PrintName<T>(string prefix) where T : class
    {
        Console.WriteLine(prefix + " " + typeof(T).FullName);
    }
}

আপনি কীভাবে এই পদ্ধতিটি প্রতিবিম্ব ব্যবহার করে প্রার্থনা করতে পারেন?

এটি খুব সহজ হতে দেখা যাচ্ছে ... আপনি প্রতিবিম্ব ব্যবহার করে এভাবেই একটি স্ট্যাটিক জেনেরিক পদ্ধতিটি আহ্বান করেন:

// Grabbing the type that has the static generic method
Type typeofClassWithGenericStaticMethod = typeof(ClassWithGenericStaticMethod);

// Grabbing the specific static method
MethodInfo methodInfo = typeofClassWithGenericStaticMethod.GetMethod("PrintName", System.Reflection.BindingFlags.Static | BindingFlags.Public);

// Binding the method info to generic arguments
Type[] genericArguments = new Type[] { typeof(Program) };
MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);

// Simply invoking the method and passing parameters
// The null parameter is the object to call the method from. Since the method is
// static, pass null.
object returnValue = genericMethodInfo.Invoke(null, new object[] { "hello" });

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