Pregunta

Given a method passed an Action or Function delegate, I can't recall if I actually have to make a local copy and test for null before invoking... or if that's already handled by the fact that it's passed in as a parameter? (Google is failing me right now)

Can p_transformer be null'd in Foo1 if the for loop is iterating while some other thread nulls the external reference to it requiring a format more like Foo2 where a local copy of the delegate is made first?

Foo1

using System;
using System.Linq;
using System.Collections.Generic;

namespace Extensions
{
    public static partial class ExtensionMethods
    {
        public static IEnumerable<T> foo1<T>(this List<T> p_someList, Func<int, T> p_transformer = null)
        {
            if (Object.Equals(p_someList, null))
                throw new ArgumentNullException("p_someList cannot be null.", default(Exception));

            if (p_someList.Count == 0)
                throw new ArgumentException("p_someList cannot be empty.");


            if (p_transformer != null)
            {
                for (int i = 0; i < p_someList.Count; i++)
                {
                    p_someList[i] = p_transformer(i);
                    yield return p_someList[i];
                }
            }
            else
            {
                for (int i = 0; i < p_someList.Count; i++)
                {
                    yield return p_someList[i];
                }
            }
        }
    }
}

Vs. Foo2

using System;
using System.Linq;
using System.Collections.Generic;

namespace Extensions
{
    public static partial class ExtensionMethods
    {
        public static IEnumerable<T> foo2<T>(this List<T> p_someList, Func<int, T> p_transformer = null)
        {
            if (Object.Equals(p_someList, null))
                throw new ArgumentNullException("p_someList cannot be null.", default(Exception));

            if (p_someList.Count == 0)
                throw new ArgumentException("p_someList cannot be empty.");


            var Transformer = p_transformer;
            if (Transformer != null)
            {
                for (int i = 0; i < p_someList.Count; i++)
                {
                    p_someList[i] = Transformer(i);
                    yield return p_someList[i];
                }
            }
            else
            {
                for (int i = 0; i < p_someList.Count; i++)
                {
                    yield return p_someList[i];
                }
            }
        }
    }
}
¿Fue útil?

Solución

You still need to check for null.

Consider this:

private void Caller()
{
    Func<int> func = null;
    Callee(func);
}

private void Callee(Func<int> func)
{
    func(0);  // Oops
}

However, the func parameter in the Callee() function is already a local copy.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top