C# monkey patching - is it possible?
Asked Answered
C

3

3

Is it possible to write a C# assembly which when loaded will inject a method into a class from another assembly? If yes, will the injected method be available from languages using DLR, like IronPython?

namespace IronPython.Runtime
{
    public class Bytes : IList<byte>, ICodeFormattable, IExpressionSerializable
    {
        internal byte[] _bytes;

        //I WANT TO INJECT THIS METHOD
        public byte[] getbytes()
        {
            return _bytes;
        }
    }
}

I need that method, and I would like to avoid recompiling IronPython if possible.

Ciliolate answered 17/5, 2010 at 23:34 Comment(0)
B
1

This can be done with frameworks such as TypeMock, which hook into the framework profiling APIs.

However this kind of injection is usually only used to facilitate unit testing rather than within production code and comes with a performance hit. My opinion is that if you are having to do something as drastic as this outside of unit testing, then do you are probably doing something wrong.

Blackfish answered 18/5, 2010 at 21:45 Comment(0)
P
1

It is possible to access extension methods from IronPython. See http://blogs.msdn.com/saveenr/archive/2008/11/14/consuming-extension-methods-in-ironpython.aspx

Postobit answered 21/5, 2010 at 2:6 Comment(0)
N
0

I don't believe that it's possible to extend an existing .NET type once it's created.

If all you need is a byte[] (in IronPython, I presume), you can do:

>>> import clr
>>> import System
>>> b = bytes([1, 2, 3, 4])
>>> a = System.Array[bytes](b)
>>> a
Array[bytes]((b'\x01', b'\x02', b'\x03', b'\x04'))

However, it's unlikely that IronPython will ever allow access to Bytes' underlying storage (unless CPython does), as it's not safe.

Nabila answered 18/5, 2010 at 15:11 Comment(6)
This is too slow for my needs. I have to construct millions of ctypes.Structs. I think I found a solution to inject what I need using extension methods and GetBoundMethod. Another solution would be to have a file object read/write method which uses byte[] instead of Bytes (which would be safe). The problem is that I can't pass what I read from a file with f.read() to a method implemented in a C# assembly which uses byte[], since that will actually receive a string. Currently I need to iterate over each char and manually build a byte[] from that. I have gigabytes to process.Ciliolate
I'm not a C# expert, could it allow read-only access to the underlying storage? Something like const void*.Ciliolate
Yeah, there is ReadOnlyCollection<byte>. I don't know if it copies the underlying data, though (I hope not).Nabila
Is it not possible to build a ctypes.Struct from a bytes object? Or am I misunderstanding?Nabila
The standard way, using Struct.from_buffer_copy doesn't work in IronPython (but does work in CPython)Ciliolate
So do you need a byte[] for something else, or are you trying to find a workaround for the bug in from_buffer_copy?Nabila

© 2022 - 2024 — McMap. All rights reserved.