سؤال

نأمل أن يكون هذا أمرًا بسيطًا.

أرغب في إضافة طريقة ملحق إلى فئة System.Web.Mvc.ViewPage< T >.

كيف ينبغي أن تبدو طريقة التمديد هذه؟

فكرتي البديهية الأولى هي شيء من هذا القبيل:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

حل

الحل العام هو هذه الإجابة.

الحل المحدد لتوسيع فئة System.Web.Mvc.ViewPage هو إجابتي أدناه، والتي بدأت من الحل العام.

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

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

المحلول

ليس لدي VS مثبت على جهازي الحالي، ولكن أعتقد أن بناء الجملة سيكون:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v)
        {
            return "";
        }
    }
}

نصائح أخرى

شكرا ليدت.أدى القيام بذلك إلى الخطأ:

يجب أن يكون نوع "tmodel" نوع مرجع لاستخدامه كمعلمة "tmodel" في النوع أو الطريقة العامة

الذي أشار لي هذه الصفحة, ، والتي أسفرت عن هذا الحل:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> v) 
          where T : class
        {
            return "";
        }
    }
}

يحتاج فقط إلى محدد النوع العام في الوظيفة:

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<Type>(this ViewPage<Type> v)
        {
            return "";
        }
    }
}

يحرر:غاب عنها فقط ثواني!

namespace System.Web.Mvc
{
    public static class ViewPageExtensions
    {
        public static string GetDefaultPageTitle<T>(this ViewPage<T> view)
            where T : class
        {
            return "";
        }
    }
}

قد تحتاج/ترغب أيضًا في إضافة المؤهل "new()" إلى النوع العام (أي."اين :class، new()" لفرض أن T هو نوع مرجعي (فئة) ويحتوي على مُنشئ بدون معلمات.

جلين بلوك لديه مثال جيد لتنفيذ أ ForEach طريقة التمديد ل IEnumerable<T>.

منه مشاركة مدونة:

public static class IEnumerableUtils
{
    public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
    {
        foreach(T item in collection)
            action(item);
    }
}

إذا كنت تريد أن يكون الامتداد متاحًا فقط للنوع المحدد ، فأنت ببساطة تحتاج فقط إلى تحديد النوع الفعلي الذي ستتعامل معه

شيء مثل...

public static string GetDefaultPageTitle(this ViewPage<YourSpecificType> v)
{
  ...
}

ملاحظة: سيعرض التحسس الذكي طريقة الامتداد فقط عندما تعلن عن صفحة العرض الخاصة بك (في هذه الحالة) بالنوع المطابق.

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

فيما يلي مثال لطرق عرض Razor:

public static class WebViewPageExtensions
{
    public static string GetFormActionUrl(this WebViewPage view)
    {
        return string.Format("/{0}/{1}/{2}", view.GetController(), view.GetAction(), view.GetId());
    }

    public static string GetController(this WebViewPage view)
    {
        return Get(view, "controller");
    }

    public static string GetAction(this WebViewPage view)
    {
        return Get(view, "action");
    }

    public static string GetId(this WebViewPage view)
    {
        return Get(view, "id");
    }

    private static string Get(WebViewPage view, string key)
    {
        return view.ViewContext.Controller.ValueProvider.GetValue(key).RawValue.ToString();
    }
}

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

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