Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ref locals to get class fields in Plugs #25

Open
fanoI opened this issue Nov 3, 2017 · 1 comment
Open

Use ref locals to get class fields in Plugs #25

fanoI opened this issue Nov 3, 2017 · 1 comment

Comments

@fanoI
Copy link
Contributor

fanoI commented Nov 3, 2017

When there is the need to access a field of a class you have to add a ref variable to one of its plug method and use the attribute "FieldAccess" this could be easily become ugly when you need to access a lot of fields:

public static void Ctor(StreamWriter aThis, string path, bool append, Encoding encoding, int bufferSize,
                         [FieldAccess(Name = "System.IO.Stream System.IO.StreamWriter._stream")] ref Stream _stream,
                         [FieldAccess(Name = "System.Int32 System.IO.StreamWriter._charPos")] ref int _charPos,
                         [FieldAccess(Name = "System.Char[] System.IO.StreamWriter._charBuffer")] ref int _charLen,
                         [FieldAccess(Name = "System.Char[] System.IO.StreamWriter._charBuffer")] ref char[] _charBuffer,
                         [FieldAccess(Name = "System.Byte[] System.IO.StreamWriter._byteBuffer")] ref byte[] _byteBuffer,
                         [FieldAccess(Name = "System.Char[] System.IO.TextWriter.CoreNewLine")] ref char[] CoreNewLine
                        )

I've had two constructors to plug (one that take a String representing a File Path and an other in which you pass a Stream already created) and so the ideal solution would have been to use an utility function to initialize all the field but I will have to pass all the ref variables and their value to it that well defeat the purpose of it a lot!

My idea is leaving the attribute version for the old code (or replace it if we are so brave) and to use ref locals introduced in C# 7 to resolve this problem so the Init() would become:

private static void Init(Stream stream, bool append, CosmosEncoding encoding, int bufferSize,  bool shouldLeaveOpen) 
{
    ref Stream _stream = ref GetFieldAccess("System.IO.Stream System.IO.StreamWriter._stream");
    ref int _charPos = ref GetFieldAccess("System.Int32 System.IO.StreamWriter._charPos");
    ref char[] _charBuffer = ref GetFieldAccess("System.Char[] System.IO.StreamWriter._charBuffer");
    ref byte[] _byteBuffer = ref  GetFieldAccess("System.Byte[] System.IO.StreamWriter._byteBuffer");
    ref char[] CoreNewLine = ref  GetFieldAccess("System.Char[] System.IO.TextWriter.CoreNewLine");

    _stream = stream;
    [...]
}      

GetFieldAccess should have these prototypes:

ref object GetFieldAccess(String FieldName);
ref object[] GetFieldAccess(String FieldName);
unsafe ref void *GetFieldAccess(String FieldName); // Not working in C# 7.0 should be added in future releases
@fanoI
Copy link
Contributor Author

fanoI commented Nov 3, 2017

Another way make easier to access to field is to add the possibility to plug a field explicitly without the needed of a plug method.

Taking this example again one could write:

public static class StreamWriterImpl
{
[PlugField name="System.IO.Stream System.IO.StreamWriter._stream"] Stream stream;

With a little of compiler "trickery" we will obtain that: stream wouldn't change
it wouldn't even be compiled if we want when loading or storing that field, the compiler would load or store _stream instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant