سؤال

وأنا محاولة استخدام طرق الإرشاد لإضافة الزائد operater إلى فئة C # 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 الكلمة في هذا السياق.

هل مضيفا الزائدة المشغل عبر طرق الإرشاد ممكن؟ إذا كان الأمر كذلك، ما هي الطريقة الصحيحة للذهاب نحو ذلك؟

هل كانت مفيدة؟

المحلول

وهذا غير ممكن في الوقت الراهن، لأن طرق الإرشاد يجب أن يكون في صفوف ساكنة، والطبقات ثابتة لا يمكن أن يكون الزائدة المشغل.

ومادس تورجيرسين، C # PM اللغة يقول:

<اقتباس فقرة>   

... من أجل إطلاق سراح دلافين أوكرا قررنا   تتخذ نهجا حذرا وإضافة   طرق الإرشاد العادية فقط، كما   بدلا من خصائص ارشادية،   أحداث والمشغلين وأساليب ثابتة، الخ   كانت وما طرق الإرشاد منتظم   ما كنا بحاجة لLINQ، وكان لديهم   بساطة التصميم نحويا أن   لا يمكن تحاكي بسهولة لبعض   من أنواع الأعضاء الأخرى.

     

وأصبحنا أكثر وعيا   أن أنواع أخرى من أعضاء التمديد   يمكن أن تكون مفيدة، وهكذا سنعود   لهذه القضية بعد دلافين أوكرا. لا   ضمانات، على الرغم من!

وتحرير:

ولقد لاحظت فقط، كتب مادس أكثر في نفس المادة :

<اقتباس فقرة>   

ويؤسفني أن أبلغكم بأننا سوف لا   أن تفعل هذا في الإصدار التالي. نحن   لم يأخذ أعضاء تمديد جدا   على محمل الجد في خططنا، وأمضى   الكثير من الجهد في محاولة للحصول عليها   الحق، ولكن في النهاية لم نتمكن من الحصول على   على نحو سلس بما فيه الكفاية، وقررت إعطاء   الطريق إلى ميزات أخرى مثيرة للاهتمام.

     

وهذا لا يزال على رادار لدينا في المستقبل   إطلاق. ما سوف يساعد هو اذا حصلنا على   كمية لا بأس بها من سيناريوهات مقنعة   التي يمكن أن تساعد دفع التصميم الصحيح.


هذه الميزة حاليا على الطاولة (يحتمل) لC # 8.0. مادس محادثات أكثر قليلا عن تنفيذه <لأ href = "https://channel9.msdn.com/Blogs/Seth-Juarez/A-Preview-of-C-8-with-Mads-Torgersen#time=32m11s" يختلط = " noreferrer "> هنا .

نصائح أخرى

إذا كنت السيطرة على الأماكن التي ترغب في استخدام هذه "المشغل التمديد" (والتي تفعل عادة مع طرق الإرشاد على أي حال)، يمكنك أن تفعل شيئا من هذا القبيل:

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 تعلن على ضمني عامل تحويل من 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 أكثر قابلية للفهم.

ويبدو هذا غير الممكن حاليا - هناك مسألة ردود الفعل مفتوحة طلب هذه الميزة بالذات على اتصال Microsoft:

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

ومما يشير إلى أنه قد تظهر في إصدار مستقبلي ولكن لم يتم تنفيذ للإصدار الحالي.

وعلى الرغم من أنه من غير الممكن للقيام المشغلين، هل يمكن دائما مجرد خلق اضافة (أو CONCAT)، طرح، وقارن أساليب ....

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;    
        }
    }


}

وهاه! كنت أبحث عن "مشغل تمديد الحمولة الزائدة" مع بالضبط نفس الرغبة، لبينالي الشارقة + = (الشيء).

وبعد قراءة الإجابات هنا (ورؤية أن الجواب هو "لا")، لبلدي الاحتياجات الخاصة، وذهبت مع طريقة التمديد الذي يجمع بين sb.AppendLine وsb.AppendFormat، ويبدو أرتب من أي.

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);

وليس إجابة عامة، ولكن قد تكون ذات فائدة للباحثين في المستقبل النظر في هذا النوع من الشيء.

ولها ممكن لريج ذلك مع المجمع وملحقات ولكن من المستحيل ان تفعل ذلك بشكل صحيح. ينتهي بك مع القمامة التي الهزائم تماما الغرض. لدي وظيفة في مكان ما هنا أن يفعل ذلك، ولكن لها قيمة لها.

وراجع للشغل كل التحويلات الرقمية خلق القمامة في بناء السلسلة التي تحتاج إلى إصلاح. كان لي لكتابة مجمع لتلك التي يعمل وأنا استخدامها. وهذا هو يستحق يلاحقونهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top