, , eg. Action<Fruit> , Action<Banana>, , Action<Fruit> Action<Banana> *, Action<Banana>. , :
static T As<T>(this Delegate del) where T : class
{
if (del == null || del.GetType() == typeof(T)) return (T)(Object)del;
Delegate[] invList = ((Delegate)(Object)del).GetInvocationList();
for (int i = 0; i < invList.Length; i++)
if (invList[i].GetType() != typeof(T))
invList[i] = Delegate.CreateDelegate(typeof(T), invList[i].Target, invList[i].Method);
return (T)(Object)Delegate.Combine(invList);
}
, , ; , , . , , , , , , . , , Action<string>, , . Action<object> "" Action<string> .
- , Intellisense, :
static void AppendTo<T>(this Delegate newDel, ref T baseDel) where T : class
{
newDel = (Delegate)(Object)newDel.As<T>();
T oldBaseDel, newBaseDel;
do
{
oldBaseDel = baseDel;
newBaseDel = (T)(Object)Delegate.Combine((Delegate)(object)oldBaseDel, newDel);
} while (System.Threading.Interlocked.CompareExchange(ref baseDel, newBaseDel, oldBaseDel) != oldBaseDel);
}
static void SubtractFrom<T>(this Delegate newDel, ref T baseDel) where T : class
{
newDel = (Delegate)(Object)newDel.As<T>();
T oldBaseDel, newBaseDel;
do
{
oldBaseDel = baseDel;
newBaseDel = (T)(Object)Delegate.Remove((Delegate)(object)oldBaseDel, newDel);
} while (System.Threading.Interlocked.CompareExchange(ref baseDel, newBaseDel, oldBaseDel) != oldBaseDel);
}
, Delegate, ; - , / .