كيف يمكنني استدعاء تطبيقاتي الخاصة لأعضاء الواجهة؟


أحاول إنشاء فصل دراسي (قياس) التي يجب أن تحاكي فئات C# الرقمية الداخلية (كثافة العمليات, مزدوج, يطفوالخ) قدر الإمكان. ولتحقيق هذه الغاية قمت بتحديد قياس أن يكون للفئة تطبيقاتها الخاصة للطرق المستخدمة من قبل فئات C#.

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

يتضمن صفي ما يلي من أجل تحديد تريكونفيرتفرومتشيكيد () طريقة:

ج#
public partial class Measurement<T> : ..., INumberBase<Measurement<T>>,...
        where T : ...,INumberBase<T>, ...
    {
...
        /// <inheritdoc cref="INumberBase{TSelf}.TryConvertFromChecked{TOther}(TOther, out TSelf)" />
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static bool INumberBase<Measurement<T>>.TryConvertFromChecked<TOther>(TOther value, [MaybeNullWhen(false)] out Measurement<T> result)
        {
            return TryConvertFrom(value, out result, ConversionOption.Checked);
        }

        private static bool TryConvertFrom<TOther>([NotNull] TOther value, [MaybeNullWhen(false)] out Measurement<T> result, ConversionOption option)
            where TOther : INumberBase<TOther>
        {
            ...
        }
...
    }

وأحاول أن أسمي هذه الطريقة على النحو التالي:

ج#
if (!T.TryConvertFromChecked(toUnit.CompoundFactor, out var toCompoundFactor))
    {
        throw new ApplicationException($"An internal error occurred while converting the CompoundFactor for [{unitSymbol}] from type [{toUnit.CompoundFactor}] to type [{typeof(T)}]");
    }

ولكن هذا دائمًا هو تنفيذ C# الداخلي System.Numerics.INumberBase تطبيق. كيف يمكنني الحصول على مكالمتي ل تريكونفيرتفرومتشيكيد () للاتصال بالشخص الذي قمت بإنشائه؟

ما حاولت:

ج#
if (!T.Measurement<T>.TryConvertFromChecked(toUnit.CompoundFactor, out var toCompoundFactor))

النتائج في CS0704 لا يمكن إجراء بحث عن الأعضاء غير الظاهريين في ‘T’ لأنه معلمة نوع

الحل 1

هنا مشكلتك:

ج#
T.TryConvertFromChecked(toUnit.CompoundFactor, out var toCompoundFactor)

وهذا يدعو TryConvertFromChecked في ال readonly struct Double. هنا هي الطريقة:

ج#
static bool INumberBase<double>.TryConvertFromChecked<TOther>(TOther value, out double result)
{
    return TryConvertFrom<TOther>(value, out result);
}

و ال TryConvertFrom:

ج#
private static bool TryConvertFrom<TOther>(TOther value, out double result)
    where TOther : INumberBase<TOther>
{
    // In order to reduce overall code duplication and improve the inlinabilty of these
    // methods for the corelib types we have `ConvertFrom` handle the same sign and
    // `ConvertTo` handle the opposite sign. However, since there is an uneven split
    // between signed and unsigned types, the one that handles unsigned will also
    // handle `Decimal`.
    //
    // That is, `ConvertFrom` for `double` will handle the other signed types and
    // `ConvertTo` will handle the unsigned types

    if (typeof(TOther) == typeof(Half))
    {
        Half actualValue = (Half)(object)value;
        result = (double)actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(short))
    {
        short actualValue = (short)(object)value;
        result = actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(int))
    {
        int actualValue = (int)(object)value;
        result = actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(long))
    {
        long actualValue = (long)(object)value;
        result = actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(Int128))
    {
        Int128 actualValue = (Int128)(object)value;
        result = (double)actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(nint))
    {
        nint actualValue = (nint)(object)value;
        result = actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(sbyte))
    {
        sbyte actualValue = (sbyte)(object)value;
        result = actualValue;
        return true;
    }
    else if (typeof(TOther) == typeof(float))
    {
        float actualValue = (float)(object)value;
        result = actualValue;
        return true;
    }
    else
    {
        result = default;
        return false;
    }
}

التحويل غير مفتوح للتخصيص بالطريقة التي تريدها. سيكون من الأفضل لك النظر في استخدام فئة TypeConverter (System.ComponentModel) | مايكروسوفت تعلم[^]

ومع ذلك، إذا كنت لا تزال ترغب في السير في هذا الطريق، فقم بإلقاء نظرة على متصفح مصدر .NET – BigInteger[^] لنرى كيف تتعامل مايكروسوفت معها.

コメント

タイトルとURLをコピーしました