سؤال

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

لقد حاولت استخدام الأدوية العامة، لكني لا أعرف ما يكفي عن هذا الأمر، لذا فهو لا يعمل:

public void OuterMethod<T>(T parameter)
{
    InnerMethod(parameter); // InnerMethod accepts an int or a string
}

أعلم أنه يمكنني القيام بذلك:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter);
}

لكنني أفضل القيام بذلك بالطريقة الصحيحة بدلاً من نسخ/لصق الكود.ما هي أفضل طريقة لتحقيق ذلك؟

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

المحلول

ويمكنك القيام بذلك في C ++ ولكن ليس في C # (إلا إذا كان الأسلوب الداخلي ويمكن أيضا أن يكون عام بدلا من طاقتها).


وبدلا من ذلك (إذا كنت لن تأخذ "لا" للإجابة)، يمكنك القيام التبديل وقت التشغيل على نوع، منها على سبيل المثال ...

public void OuterMethod(object parameter)
{
    if (parameter is int)
        InnerMethod((int)parameter);
    else if (parameter is string)
        InnerMethod((string)parameter);
    else
        throw new SomeKindOfException();
}

و... ولكن من الواضح أن هذا هو وقت التشغيل، وليس الاختيار وقت الترجمة.

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

ولكن كنت تفعل بدلا هذا الطريق الصحيح بدلا من نسخ / لصق التعليمات البرمجية.

ويمكنك أيضا كتابة البرامج لكتابة أساليب الخارجي الخاص بك (على سبيل المثال باستخدام الفئات System.CodeDom) بدلا من كتابتها بخط اليد، ولكن هذا هو على الارجح المزيد من المتاعب أكثر مما يستحق.

نصائح أخرى

وقال مثل الآخرين، لا يمكنك حقا ما تحاول القيام به، والخيار الذي ورد في سؤالك هو أفضل رهان.

وأنت لن يكون في الواقع لتحويل القيمة إذا كنت تستخدم عامة. وإلا يمكنك مسبل بقبول كائن كما يقترح ChrisW.

 public void OuterMethod<T>(T parameter) 
            {
                T temp = parameter;
                if (temp is string )
                    InnerMethod(Convert.ToString(temp));
                if (temp is int)
                    InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
            }

وهنا رابط لمحة عامة عن الوراثة: HTTP: // MSDN .microsoft.com / EN-US / مكتبة / ms172193.aspx

ومن وصفك هذا يبدو وكأنه أكثر الأمثل.

وماذا عن:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter**.ToString()**);
}

يمكنك استخدام أ dynamic اكتب لتأجيل حل التحميل الزائد حتى وقت التشغيل.

public void OuterMethod(dynamic parameter)
{
    InnerMethod(parameter);
}

public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }

تنبيه قضائي لا يتم حل التعبيرات من النوع الديناميكي أو يتم فحص النوع بواسطة المترجم. وقد تكون هناك عقوبة على الأداء أيضًا.

إذا OuterMethod يدعو دائما InnerMethod، وInnerMethod لا يقبل إلا عدد صحيح أو سلسلة، ثم OuterMethod لا تجعل أي معنى.

وإذا كان <م> فقط الفرق هو أن واحدا يدعو InnerMethod (الباحث) ونداءات أخرى InnerMethod (سلسلة) هل يمكن أن تفعل شيئا من هذا القبيل:

public void OuterMethod(string parameter)
{
    InnerMethodA(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethodA(parameter);
}

private void InnerMethodA(object parameter)
{
    // Whatever other implementation stuff goes here

    if (parameter is string)
    {
        InnerMethodB((string) parameter);
    }
    else if (parameter is int)
    {
        InnerMethodB((string) parameter);
    }
    else
    {
        throw new ArgumentException(...);
    }
}

private void InnerMethodB(string parameter)
{
    // ...
}

private void InnerMethodB(int parameter)
{
    // ...
}

وطيب عندي وضعا مماثلا، في طريقة التحكم في الوصول في منطق عملي.

وهناك وظيفة حفظ التي يمكن تطبيقها على أي من بلدي بيرسيستانسي الأجسام طبقة.

وبحيث يبدو مثل هذا

public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
    if(CanWrite(user, entity))
    {
        entity.save();
    }
    else
    {
        throw new Exception("Cannot Save");
    }
}

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

public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
        {
            int? clubId = null;
            MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
            if(methodInfo != null)
            {
                return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
            }
            else 
            {
                //generic answer
            }
            return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
        }

والآن في كل مرة أقوم بإضافة أو إزالة الطريقة، ليس لدي سوى لإضافة أو إزالة في مكان واحد

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