কোনও এক্সটেনশন পদ্ধতি সহ কোনও শ্রেণি পদ্ধতিতে ওভাররাইড করার জন্য কি সি # তে কোনও উপায় আছে?


100

এমন কিছু অনুষ্ঠান হয়েছে যেখানে আমি ক্লাসে কোনও এক্সটেনশন পদ্ধতি সহ কোনও পদ্ধতিকে ওভাররাইড করতে চাই। সি # তে করার কোনও উপায় আছে কি?

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

public static class StringExtension
{
    public static int GetHashCode(this string inStr)
    {
        return MyHash(inStr);
    }
}

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

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

আমি জানি যে আমি এটি বিদ্যমান ক্লাসের সাবক্লাসিংয়ের মাধ্যমে করতে পারলাম তবে এটি অনেক ক্ষেত্রেই একটি এক্সটেনশান সহ এটি করতে সক্ষম হবেনা সহজ y


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

উত্তর:


94

না; কোনও এক্সটেনশন পদ্ধতি কোনও উপযুক্ত স্বাক্ষর সহ কোনও উদাহরণ পদ্ধতির GetHashCodeতুলনায় কখনই অগ্রাধিকার নেয় না এবং পলিমারফিজমে কখনও অংশ নেয় না ( এটি একটি virtualপদ্ধতি)।


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

4
@ অ্যালেক্স ভার্চুয়াল উল্লেখ করে আমি বহুবচন হওয়ার অর্থ কী তা কেবল পরিষ্কার করছি am কার্যত গেটহ্যাশকোডের সমস্ত ব্যবহারের ক্ষেত্রে, কংক্রিটের ধরণ অজানা - সুতরাং বহুবর্ষটি চলছে। এর মতো, নিয়মিত সংকলকটিতে অগ্রাধিকার নিয়ে থাকলেও সম্প্রসারণের পদ্ধতিগুলি সাহায্য করবে না । ওপি আসলে যা চায় তা হচ্ছে বানর-প্যাচিং। কোন সি # এবং .NET সুবিধা দেয় না।
মার্ক Gravell

4
এটি দুঃখজনক, সি # তে অনেকগুলি বিভ্রান্তিমূলক অ-জ্ঞান পদ্ধতি, যেমন .ToString()অ্যারেগুলিতে। এটি অবশ্যই প্রয়োজনীয় বৈশিষ্ট্য।
হাই-এঞ্জেল

আপনি কেন তখন একটি সংকলক ত্রুটি পান না? যেমন আমি টাইপ করি। namespace System { public static class guilty { public static string ToLower(this string s) { return s.ToUpper() + " I'm Malicious"; } } }
লোভিল

নিবন্ধন করুন
মার্ক গ্র্যাভেল

7

যদি পদ্ধতিটির আলাদা স্বাক্ষর থাকে তবে এটি করা যায় - সুতরাং আপনার ক্ষেত্রে: না।

তবে অন্যথায় আপনি যা খুঁজছেন তা করার জন্য আপনার উত্তরাধিকার ব্যবহার করা দরকার।


2

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


0

আমি ক্লাস পদ্ধতি হিসাবে একই স্বাক্ষর সহ একটি এক্সটেনশন পদ্ধতিটি আহ্বানের একটি উপায় খুঁজে পেয়েছি, তবে এটি খুব মার্জিত বলে মনে হয় না। এক্সটেনশন পদ্ধতিগুলি নিয়ে ঘুরে দেখার সময় আমি কিছু অনিবন্ধিত আচরণ লক্ষ্য করেছি। কোডের উদাহরণ:

public static class TestableExtensions
{
    public static string GetDesc(this ITestable ele)
    {
        return "Extension GetDesc";
    }

    public static void ValDesc(this ITestable ele, string choice)
    {
        if (choice == "ext def")
        {
            Console.WriteLine($"Base.Ext.Ext.GetDesc: {ele.GetDesc()}");
        }
        else if (choice == "ext base" && ele is BaseTest b)
        {
            Console.WriteLine($"Base.Ext.Base.GetDesc: {b.BaseFunc()}");
        }
    }

    public static string ExtFunc(this ITestable ele)
    {
        return ele.GetDesc();
    }

    public static void ExtAction(this ITestable ele, string choice)
    {
        ele.ValDesc(choice);
    }
}

public interface ITestable
{

}

public class BaseTest : ITestable
{
    public string GetDesc()
    {
        return "Base GetDesc";
    }

    public void ValDesc(string choice)
    {
        if (choice == "")
        {
            Console.WriteLine($"Base.GetDesc: {GetDesc()}");
        }
        else if (choice == "ext")
        {
            Console.WriteLine($"Base.Ext.GetDesc: {this.ExtFunc()}");
        }
        else
        {
            this.ExtAction(choice);
        }
    }

    public string BaseFunc()
    {
        return GetDesc();
    }
}

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

কোডটি পরীক্ষা করা হচ্ছে:

var bt = new BaseTest();
bt.ValDesc("");
//Output is Base.GetDesc: Base GetDesc
bt.ValDesc("ext");
//Output is Base.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext def");
//Output is Base.Ext.Ext.GetDesc: Extension GetDesc
bt.ValDesc("ext base");
//Output is Base.Ext.Base.GetDesc: Base GetDesc

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

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

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