Selective updates to immutable types
You should be able to cut the code length and improve performance, by simplifying the algorithm. Here are some of the problems I've noticed in your implementation:


You're currently processing all of the type's properties, this is not necessary as you only need few concrete ones. There are few other problems deriving from this one.
You're creating the instance through the Activator class while you're also requesting the constructor of the class, since you already have the ConstructorInfo, it doesn't make much sense to call Activator.CreateInstance. Especially since the Activator is the slowest way to create an instance of a type. You should only stick to one of them, in this case you need information that is contained in the ConstructorInfo, I guess the choice is obvious.


A simpler version (using your Target method):

public static TSource With&lt;TSource, TProperty&gt;(this TSource source,
    Expression&lt;Func&lt;TSource, TProperty&gt;&gt; selector, TProperty value)
{
    var constructor = typeof(TSource).GetConstructors().Single();
    var parameters = GenerateParameters(source, constructor,
        new KeyValuePair&lt;string, object&gt;(selector.Target(), value)).ToArray();
    return (TSource) constructor.Invoke(parameters);
}

private static IEnumerable&lt;object&gt; GenerateParameters&lt;TSource&gt;(
    TSource source, ConstructorInfo ctor,
    KeyValuePair&lt;string, object&gt; parameterToModify)
{
    var type = typeof(TSource);
    foreach (var parameter in ctor.GetParameters())
    {
        if (string.Equals(parameter.Name, parameterToModify.Key, StringComparison.OrdinalIgnoreCase))
        {
            yield return parameterToModify.Value;
        }
        else
        {
            yield return type.GetProperty(parameter.Name,
                BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance)?.GetValue(source);
        }
    }
}


I'm not a fan of long ternary operators, but if you prefer that you can always switch it. I don't really like KeyValuePair&lt;,&gt; either, but it makes sense to keep things coupled and adding a separate class seems somewhat redundant as it will be used only in 1 occasion.

This is the cleaner approach, but if you really want to squeeze a bit more performance you can avoid the .ToArray() call by creating an object[] instead of IEnumerable&lt;object&gt;:

public static TSource With&lt;TSource, TProperty&gt;(this TSource source,
    Expression&lt;Func&lt;TSource, TProperty&gt;&gt; selector, TProperty value)
{
    var constructor = typeof(TSource).GetConstructors().Single();
    return (TSource) constructor.Invoke(GenerateParameters(source, constructor,
        new KeyValuePair&lt;string, object&gt;(selector.Target(), value)));
}

private static object[] GenerateParameters&lt;TSource&gt;(
    TSource source, ConstructorInfo ctor,
    KeyValuePair&lt;string, object&gt; parameterToModify)
{
    var type = typeof(TSource);
    var ctorParameters = ctor.GetParameters();
    var parameters = new object[ctorParameters.Length];
    for (int i = 0; i &lt; parameters.Length; i++)
    {
        var ctorParameter = ctorParameters[i];
        if (string.Equals(ctorParameter.Name, parameterToModify.Key, StringComparison.OrdinalIgnoreCase))
        {
            parameters[i] = parameterToModify.Value;
        }
        else
        {
            parameters[i] = type.GetProperty(ctorParameter.Name,
                BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance)?.GetValue(source);
        }
    }
    return parameters;
}


It's a bit longer, but it's not necessarily less readable, you can pick whatever suits you better.

P.S

Perhaps some caching mechanism would be useful, to improve performance of multiple sequential calls.