هل يمكنني استخدام params في العمل أو مندوبي FUNC؟
-
27-09-2019 - |
سؤال
عندما أحاول استخدام المعلمات في مندوب الإجراء ...
private Action<string, params object[]> WriteToLogCallBack;
تلقيت خطأ وقت التصميم هذا:
الرمز المميز غير الصالح "params" في إعلان الأعضاء في الفصل أو البنية أو الواجهة
أي مساعدة!
المحلول
ماذا عن هذا الحل؟
private Action<string, object[]> writeToLogCallBack;
public void WriteToLogCallBack(string s, params object[] args)
{
if(writeToLogCallBack!=null)
writeToLogCallBack(s,args);
}
أو يمكنك تحديد نوع المندوب الخاص بك:
delegate void LogAction(string s, params object[] args);
نصائح أخرى
معلمات النوع المتغير غير ممكنة في C#.
لهذا السبب هناك العديد من الإعلانات Action<...>
, Func<...>
, ، و Tuple<...>
, ، فمثلا. سيكون ميزة مثيرة للاهتمام ، رغم ذلك. C ++ 0x لديه.
يمكنك تجربة هذا. يسمح بأي عدد من الوسائط ، وستحصل على خطأ في وقت الترجمة إذا قمت بتمرير الرقم الخطأ أو نوع الوسائط.
public delegate T ParamsAction<T>(params object[] oArgs);
public static T LogAction<T>(string s, ParamsAction<T> oCallback)
{
Log(s);
T result = oCallback();
return T;
}
Foo foo = LogAction<Foo>("Hello world.", aoArgs => GetFoo(1,"",'',1.1));
يمكنك استخدام params
في الإعلان الفعلي لمندوب ، ولكن ليس في نوع واحد. المعلمات العامة لإجراء ما هي أنواع فقط ، وليس الوسائط الفعلية التي سيتم تمريرها عند استدعاء المندوب. Params ليس نوعًا ، فهي كلمة رئيسية.
لقد قمت بتمديد بسيط إلى الكود أعلاه من برايان ، لإظهار كيفية لف مكالمات طريقة متعددة.
أنا أستخدم هذا لالتفاف طرق متعددة تحتوي على مكالمات قاعدة البيانات ، في معاملة واحدة.
شكرا برايان :-)
(يمكنك تشغيل ما يلي في linqpad للاختبار)
//Wrapper code
public delegate void MyAction(params object[] objArgs);
public static void RunActions(params MyAction[] actnArgs)
{
Console.WriteLine("WrapperBefore: Begin transaction code\n");
actnArgs.ToList().ForEach( actn => actn() );
Console.WriteLine("\nWrapperAfter: Commit transaction code");
}
//Methods being called
public void Hash (string s, int i, int j) => Console.WriteLine(" Hash-method call: " + s + "###" + i.ToString() + j.ToString());
public void Slash (int i, string s) => Console.WriteLine(" Slash-method call: " + i.ToString()+ @"////" + s);
//Actual calling code
void Main()
{
RunActions( objArgs => Hash("One", 2, 1)
,objArgs => Slash(3, "four") );
}
//Resulting output:
//
// WrapperBefore: Begin transaction code
//
// Hash-method call: One###21
// Slash-method call: 3////four
//
// WrapperAfter: Commit transaction code