সি # এক্সটেনশন পদ্ধতিগুলির সাহায্যে অপারেটর ওভারলোডিং


174

আমি সি # StringBuilderশ্রেণিতে অপারেটর ওভারলোড যুক্ত করতে এক্সটেনশন পদ্ধতিগুলি ব্যবহার করার চেষ্টা করছি । বিশেষত, প্রদত্ত StringBuilder sb, আমি এর sb += "text"সমতুল্য হতে চাই sb.Append("text")

এর জন্য একটি এক্সটেনশন পদ্ধতি তৈরির জন্য সিনট্যাক্সটি এখানে রয়েছে StringBuilder:

public static class sbExtensions
{
    public static StringBuilder blah(this StringBuilder sb)
    {
        return sb;
    }
} 

এটি সাফল্যের সাথে blahএক্সটেনশন পদ্ধতিটি যুক্ত করে StringBuilder

দুর্ভাগ্যক্রমে, অপারেটর ওভারলোডিং কাজ করছে বলে মনে হয় না:

public static class sbExtensions
{
    public static StringBuilder operator +(this StringBuilder sb, string s)
    {
        return sb.Append(s);
    }
} 

অন্যান্য ইস্যুগুলির মধ্যে, কী-ওয়ার্ডটি thisএই প্রসঙ্গে অনুমোদিত নয়।

এক্সটেনশন পদ্ধতিগুলির মাধ্যমে অপারেটর ওভারলোডগুলি যুক্ত করা কি সম্ভব? যদি তা হয় তবে এটি সম্পর্কে সঠিক উপায় কী?


4
যদিও প্রথমে এটি একটি দুর্দান্ত ধারণা বলে মনে হচ্ছে, অন্যরকম এসবি = এসবি + "হাই" বিবেচনা করুন;
হ্যাচেট -

উত্তর:


150

এটি বর্তমানে সম্ভব নয়, কারণ এক্সটেনশন পদ্ধতিগুলি অবশ্যই স্ট্যাটিক ক্লাসে থাকতে পারে এবং স্ট্যাটিক শ্রেণিতে অপারেটর ওভারলোড থাকতে পারে না।

ম্যাডস টর্গারসেন, সি # ভাষার প্রধানমন্ত্রী বলেছেন:

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

আমরা ক্রমবর্ধমানভাবে সচেতন হয়ে উঠছি যে অন্যান্য ধরণের এক্সটেনশন সদস্য কার্যকর হতে পারে, এবং তাই আমরা অর্কেসের পরে এই বিষয়ে ফিরে আসব। কোনও গ্যারান্টি নেই, যদিও!

সম্পাদনা:

আমি কেবল লক্ষ্য করেছি, ম্যাডস একই লেখায় আরও লিখেছেন :

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

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


এই বৈশিষ্ট্যটি বর্তমানে সি # 8.0 এর জন্য টেবিলে (সম্ভাব্যভাবে) রয়েছে। ম্যাডস এখানে এটি প্রয়োগের বিষয়ে আরও কিছু কথা বলে ।


এই পৃষ্ঠাটি তখন থেকে নামানো হয়েছে; এই সমস্যা এখনও সমাধান করা হয় না।
ক্রিস মোসচিনি

17
খুব খারাপ. আমি কেবল একটি স্কেলারের মান দিয়ে
টাইমস্প্যানকে গুণতে

আমি Stringপাওয়ারশেলটিতে কাস্ট করার জন্য একই ধারণাটি বাস্তবায়নের আশা করছিলাম ScriptBlock
ট্রেভর সুলিভান

এর অর্থ আমি জোর বেটউইন বুলিয়ান হতে% কে ওভারলোড করতে পারি না? :( মৃত true.Xor(false)তারপর
স্পার্ক

3
@ স্পার্ক ^সি # -র জ্যাকার অপারেটর
জ্যাকব ক্রল

57

আপনি যদি এই "এক্সটেনশন অপারেটর" ব্যবহার করতে চান এমন জায়গাগুলি নিয়ন্ত্রণ করেন (যা আপনি সাধারণত যেভাবেই এক্সটেনশন পদ্ধতিতে করেন) তবে আপনি এরকম কিছু করতে পারেন:

class Program {

  static void Main(string[] args) {
    StringBuilder sb = new StringBuilder();
    ReceiveImportantMessage(sb);
    Console.WriteLine(sb.ToString());
  }

  // the important thing is to use StringBuilderWrapper!
  private static void ReceiveImportantMessage(StringBuilderWrapper sb) {
    sb += "Hello World!";
  }

}

public class StringBuilderWrapper {

  public StringBuilderWrapper(StringBuilder sb) { StringBuilder = sb; }
  public StringBuilder StringBuilder { get; private set; }

  public static implicit operator StringBuilderWrapper(StringBuilder sb) {
    return new StringBuilderWrapper(sb);
  }

  public static StringBuilderWrapper operator +(StringBuilderWrapper sbw, string s) { 
      sbw.StringBuilder.Append(s);
      return sbw;
  }

} 

StringBuilderWrapperবর্গ একটি ঘোষণা অন্তর্নিহিত রূপান্তর অপারেটর A থেকে StringBuilder এবং আকাঙ্ক্ষিত ঘোষণা +অপারেটর। এইভাবে, একটিতে StringBuilderপাস করা যেতে পারে ReceiveImportantMessage, যা নিঃশব্দে একটিতে রূপান্তরিত হবে StringBuilderWrapper, যেখানে +অপারেটরটি ব্যবহার করা যেতে পারে।

কলারদের কাছে এই বাস্তবতাকে আরও স্বচ্ছ করতে, আপনি এটি ReceiveImportantMessageগ্রহণের মতো ঘোষণা করতে পারেন StringBuilderএবং কেবল এই জাতীয় কোড ব্যবহার করুন:

  private static void ReceiveImportantMessage(StringBuilder sb) {
    StringBuilderWrapper sbw = sb;
    sbw += "Hello World!";
  }

বা, যেখানে আপনি ইতিমধ্যে একটি ব্যবহার করছেন সেখানে ইনলাইনটি ব্যবহার করার জন্য StringBuilder, আপনি কেবল এটি করতে পারেন:

 StringBuilder sb = new StringBuilder();
 StringBuilderWrapper sbw = sb;
 sbw += "Hello World!";
 Console.WriteLine(sb.ToString());

আরও বোধগম্য করার জন্য আমি অনুরূপ পদ্ধতির ব্যবহার সম্পর্কে একটি পোস্ট তৈরি করেছি IComparable


2
@ লিওন: আমি আসলে এটি রচনা করতে চেয়েছি, এর উত্তরাধিকারসূত্রে নয়। যাইহোক, এটি সিল করা হবার পর থেকে আমি উত্তরাধিকার সূত্রে পাইনি।
জর্দো

5
@ লিওন: এই কৌশলটি এটিই হৃদয়। আমি এটি করতে পারি কারণ সেখানে একটি অন্তর্নিহিত রূপান্তর অপারেটর ঘোষণা করেছে StringBuilderWrapperযা এটি সম্ভব করে।
জর্দো

1
@ অ্যাপলওভার: আপনি ঠিক বলেছেন, এটির জন্য একটি নতুন ধরণের তৈরি করা দরকার যা StringBuilderপ্রকারটি মোড়ানো এবং এ থেকে একটি অন্তর্নিহিত রূপান্তর অপারেটর সরবরাহ করবে। এর পরে, এটি স্ট্রিং লিটারেলের সাথে ব্যবহার করা যেতে পারে, যেমন উদাহরণে প্রদর্শিত হয়েছে:sb += "Hello World!";
জর্দো

2
আমি তখন পরামর্শ দিতে পারি, এতে কোনও এক্সটেনশন পদ্ধতি যুক্ত করার জন্য String: PushIndent(" ".X(4))(এটিও বলা যেতে পারে Times)। হয়তো বা এই কন্সট্রাকটর ব্যবহার করছে: PushIndent(new String(' ', 4))
জর্দো

1
@ জর্দো: দুর্দান্ত উত্তর;)
ভিনিসিয়াস

8

এটি বর্তমানে সম্ভব নয় বলে মনে হয় - মাইক্রোসফ্ট কানেক্টে এই বৈশিষ্ট্যটির অনুরোধ করে একটি মুক্ত প্রতিক্রিয়া সমস্যা রয়েছে:

http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=168224

এটি ভবিষ্যতের প্রকাশে প্রদর্শিত হতে পারে তবে বর্তমান সংস্করণে প্রয়োগ করা হয়নি।


আপনার সঠিক অর্থ কী, "বর্তমানে সম্ভব নয়?" এটি অবশ্যই সিএলআরতে সম্ভব হবে কারণ এফ # এক্সটেনশনের সবকিছুকে সমর্থন করে।
ম্যাথু ওলানিক

1
আমি মনে করি তার মানে সি # তে সম্ভব নয়, সিএলআর নয়। পুরো এক্সটেনশন পদ্ধতির জিনিসটি যাইহোক একটি সি # সংকলক কৌশল।
tofi9

1
লিঙ্কটি এখন মারা গেছে।
সিবিহ্যাকিং

1

অপারেটরগুলি করা সম্ভব না হলেও আপনি সর্বদা কেবল অ্যাড (বা কনক্যাট), বিয়োগ এবং পদ্ধতিগুলি তুলনা করতে পারেন ...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;    

namespace Whatever.Test
{
    public static class Extensions
    {
        public static int Compare(this MyObject t1, MyObject t2)
        {
            if(t1.SomeValueField < t2.SomeValueField )
                return -1;
            else if (t1.SomeValueField > t2.SomeValueField )
            {
                return 1;
            }
            else
            {
                return 0;
            }
        }

        public static MyObject Add(this MyObject t1, MyObject t2)
        {
            var newObject = new MyObject();
            //do something  
            return newObject;

        }

        public static MyObject Subtract(this MyObject t1, MyObject t2)
        {
            var newObject= new MyObject();
            //do something
            return newObject;    
        }
    }


}

1

Hah! আমি sb + = (জিনিস) এর জন্য ঠিক একই আকাঙ্ক্ষার সাথে "এক্সটেনশন অপারেটর ওভারলোডিং" খুঁজছিলাম।

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

public static class SomeExtensions
{
    public static void Line(this StringBuilder sb, string format, params object[] args)
    {
        string s = String.Format(format + "\n", args);
        sb.Append(s);
    }

}

এবং তাই,

sb.Line("the first thing is {0}",first);
sb.Line("the second thing is {0}", second);

কোনও সাধারণ উত্তর নয়, তবে ভবিষ্যতের সন্ধানকারীদের এই ধরণের জিনিসটি দেখার পক্ষে আগ্রহী হতে পারে।


4
আমি মনে করি আপনার এক্সটেনশন পদ্ধতিটি যদি আপনি এর AppendLineপরিবর্তে নাম দিয়ে থাকেন তবে আরও ভাল পড়তে পারে Line
ডেভিডআরআর

0

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

বিটিডব্লিউ সমস্ত সংখ্যার রূপান্তর স্ট্রিং বিল্ডারে আবর্জনা তৈরি করে যা ঠিক করা দরকার। যা কাজ করে তার জন্য আমাকে একটি র‍্যাপার লিখতে হয়েছিল এবং আমি এটি ব্যবহার করি। এটি অনুধাবনযোগ্য।

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