.net Framework 4.7.2...
Compiled expressions can access private fields. When I use exactly the same expression and write it to a dynamic assembly, using CompileToMethod, I get a System.FieldAccessException while trying to read the private field. 
Is there anything I can do to allow the dynamic assembly to have the same access privileges that a compiled expression does? There is ancient lore that says you cannot. But I can't find anything resembling a primary source for that claim. I can't believe there is not some form of assembly attributes or permissioning that would allow access.
Can I do it if I save the assembly instead? (Writing cached marshalling assemblies to disk is a likely feature in the future).
The application is marshalling of structs to streams in a domain-specific computer music language. Serialization is not an option (another example of dynamic code in dynamic assemblies that violates access).
Example code:
The lambda expression successfully reads the value of the private field of ComplexStruct (given below). If the same expression is emitted to a dynamic assembly using CompileToMethod, it fails with an access exception.
    ComplexStruct s = new ComplexStruct();
    s.String1 = "abc";
    // Pick a private field (one of the backing fields for a property)
    FieldInfo fieldInfo = typeof(ComplexStruct).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)[0];
    var structArgument = Expression.Parameter(typeof(ComplexStruct));
    var lambda = Expression.Lambda<Func<ComplexStruct,String>>(
        Expression.Field(structArgument, fieldInfo), // return the value of the private field.
        structArgument);
    Func<ComplexStruct,String> fn = lambda.Compile();
    String result = fn(s);
    Assert.AreEqual(structArgument.String1, result);
A struct with private fields:
// (Complex compared to simple struct where all fields 
// are public or the struct is unmanaged in case you were wondering)
public struct ComplexStruct : IEquatable<ComplexStruct>
{
    public String String1 { get; set; } // the backing field for this property gets read.
    public String String2 { get; set; }
    public String String3 { get;  }
    public ComplexStruct(String v1, String v2)
    {
        String1 = v1;
        String2 = v2;
    }
    public bool Equals(ComplexStruct other)
    {
        return String1 == other.String1 && String2 == other.String2;
    }
}
Creation of the assembly:
    AppDomain myAppDomain = Thread.GetDomain();
    AssemblyName myAsmName = new AssemblyName();
    myAsmName.Name = "DynamicAssembly";
    this.saveAssembly = ServiceBase.DEBUG;
    assemblyBuilder = myAppDomain.DefineDynamicAssembly(
                         myAsmName,
                         saveAssembly? AssemblyBuilderAccess.RunAndSave: AssemblyBuilderAccess.RunAndCollect);