سؤال

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

ما هي أفضل طريقة لتحقيق ذلك ؟

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

المحلول

لا يوجد فوري الجواب ؛ مشغلي هي ثابتة و لا يمكن التعبير عنها في القيود - القائمة primatives لا تنفذ أي واجهة محددة (على النقيض من IComparable[<T>] والتي يمكن استخدامها لمحاكاة أكبر-أكثر / أقل-أكثر).

ومع ذلك ؛ إذا كنت فقط تريد أن تعمل ، ثم في .NET framework 3.5 هناك بعض الخيارات...

لقد وضعت مكتبة هنا التي تسمح فعالة و بسيطة الوصول إلى المشغلين مع الأدوية مثل:

T result = Operator.Add(first, second); // implicit <T>; here

ويمكن تحميلها كجزء من MiscUtil

بالإضافة إلى ذلك, في C# 4.0 ، يصبح هذا ممكن عن طريق dynamic:

static T Add<T>(T x, T y) {
    dynamic dx = x, dy = y;
    return dx + dy;
}

كما كان (نقطة واحدة) أ .صافي الإصدار 2.0, ولكن هذا هو أقل اختبارها.الخيار الآخر هو إنشاء واجهة مثل

interface ICalc<T>
{
    T Add(T,T)() 
    T Subtract(T,T)()
} 

الخ, ولكن بعد ذلك تحتاج إلى تمرير ICalc<T>; من خلال كل الطرق التي يحصل فوضوي.

نصائح أخرى

وجدت أن IL فعلا يمكن التعامل مع هذا بشكل جيد جدا.Ex.

ldarg.0
ldarg.1
add
ret

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

انظر هنا.

هناك قطعة من التعليمات البرمجية التي سرقت من internats التي تستخدم الكثير من أجل هذا.يبدو أو يبني باستخدام IL المشغلين الحسابية الأساسية.يتم كل ذلك في إطار Operation<T> فئة عامة ، كل ما عليك القيام به هو تعيين العملية المطلوبة إلى مندوب.مثل add = Operation<double>.Add.

ويستخدم مثل هذا:

public struct MyPoint
{
    public readonly double x, y;
    public MyPoint(double x, double y) { this.x=x; this.y=y; }
    // User types must have defined operators
    public static MyPoint operator+(MyPoint a, MyPoint b)
    {
        return new MyPoint(a.x+b.x, a.y+b.y);
    }
}
class Program
{
    // Sample generic method using Operation<T>
    public static T DoubleIt<T>(T a)
    {
        Func<T, T, T> add=Operation<T>.Add;
        return add(a, a);
    }

    // Example of using generic math
    static void Main(string[] args)
    {
        var x=DoubleIt(1);              //add integers, x=2
        var y=DoubleIt(Math.PI);        //add doubles, y=6.2831853071795862
        MyPoint P=new MyPoint(x, y);
        var Q=DoubleIt(P);              //add user types, Q=(4.0,12.566370614359172)

        var s=DoubleIt("ABC");          //concatenate strings, s="ABCABC"
    }
}

Operation<T> شفرة المصدر من باب المجاملة لصق بن: http://pastebin.com/nuqdeY8z

مع إسناد أدناه:

/* Copyright (C) 2007  The Trustees of Indiana University
 *
 * Use, modification and distribution is subject to the Boost Software
 * License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *  
 * Authors: Douglas Gregor
 *          Andrew Lumsdaine
 *          
 * Url:     http://www.osl.iu.edu/research/mpi.net/svn/
 *
 * This file provides the "Operations" class, which contains common
 * reduction operations such as addition and multiplication for any
 * type.
 *
 * This code was heavily influenced by Keith Farmer's
 *   Operator Overloading with Generics
 * at http://www.codeproject.com/csharp/genericoperators.asp
 *
 * All MPI related code removed by ja72. 
 */
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top