ref keyword example in .NET framework library
See the question and my original answer on StackOverflowActually, I was curious myself, so I wrote a little program that scans the .NET Framework assemblies an dumps out public methods that have at least one ref parameter. It uses mono cecil static reflection capabilities.
It discards Obsolete
and COM
-related methods (that have a lot of ref params due to their nature).
Here is the result for mscorlib, system and system.core:
Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Type SafeHandle
Method System.Void DangerousAddRef(System.Boolean& success)
Type Interlocked
Method System.Int32 Increment(System.Int32& location)
Method System.Int64 Increment(System.Int64& location)
Method System.Int32 Decrement(System.Int32& location)
Method System.Int64 Decrement(System.Int64& location)
Method System.Int32 Exchange(System.Int32& location1, System.Int32 value)
Method System.Int64 Exchange(System.Int64& location1, System.Int64 value)
Method System.Single Exchange(System.Single& location1, System.Single value)
Method System.Double Exchange(System.Double& location1, System.Double value)
Method System.Object Exchange(System.Object& location1, System.Object value)
Method System.IntPtr Exchange(System.IntPtr& location1, System.IntPtr value)
Method T Exchange(T& location1, T value)
Method System.Int32 CompareExchange(System.Int32& location1, System.Int32 value, System.Int32 comparand)
Method System.Int64 CompareExchange(System.Int64& location1, System.Int64 value, System.Int64 comparand)
Method System.Single CompareExchange(System.Single& location1, System.Single value, System.Single comparand)
Method System.Double CompareExchange(System.Double& location1, System.Double value, System.Double comparand)
Method System.Object CompareExchange(System.Object& location1, System.Object value, System.Object comparand)
Method System.IntPtr CompareExchange(System.IntPtr& location1, System.IntPtr value, System.IntPtr comparand)
Method T CompareExchange(T& location1, T value, T comparand)
Method System.Int32 Add(System.Int32& location1, System.Int32 value)
Method System.Int64 Add(System.Int64& location1, System.Int64 value)
Method System.Int64 Read(System.Int64& location)
Type Volatile
Method System.Boolean Read(System.Boolean& location)
Method System.SByte Read(System.SByte& location)
Method System.Byte Read(System.Byte& location)
Method System.Int16 Read(System.Int16& location)
Method System.UInt16 Read(System.UInt16& location)
Method System.Int32 Read(System.Int32& location)
Method System.UInt32 Read(System.UInt32& location)
Method System.Int64 Read(System.Int64& location)
Method System.UInt64 Read(System.UInt64& location)
Method System.IntPtr Read(System.IntPtr& location)
Method System.UIntPtr Read(System.UIntPtr& location)
Method System.Single Read(System.Single& location)
Method System.Double Read(System.Double& location)
Method T Read(T& location)
Method System.Void Write(System.Boolean& location, System.Boolean value)
Method System.Void Write(System.SByte& location, System.SByte value)
Method System.Void Write(System.Byte& location, System.Byte value)
Method System.Void Write(System.Int16& location, System.Int16 value)
Method System.Void Write(System.UInt16& location, System.UInt16 value)
Method System.Void Write(System.Int32& location, System.Int32 value)
Method System.Void Write(System.UInt32& location, System.UInt32 value)
Method System.Void Write(System.Int64& location, System.Int64 value)
Method System.Void Write(System.UInt64& location, System.UInt64 value)
Method System.Void Write(System.IntPtr& location, System.IntPtr value)
Method System.Void Write(System.UIntPtr& location, System.UIntPtr value)
Method System.Void Write(System.Single& location, System.Single value)
Method System.Void Write(System.Double& location, System.Double value)
Method System.Void Write(T& location, T value)
Type LazyInitializer
Method T EnsureInitialized(T& target)
Method T EnsureInitialized(T& target, System.Func`1<T> valueFactory)
Method T EnsureInitialized(T& target, System.Boolean& initialized, System.Object& syncLock)
Method T EnsureInitialized(T& target, System.Boolean& initialized, System.Object& syncLock, System.Func`1<T> valueFactory)
Type SafeBuffer
Method System.Void AcquirePointer(System.Byte*& pointer)
Type Marshal
Method System.Int32 QueryInterface(System.IntPtr pUnk, System.Guid& iid, System.IntPtr& ppv)
Method System.Reflection.MemberInfo GetMethodInfoForComSlot(System.Type t, System.Int32 slot, System.Runtime.InteropServices.ComMemberType& memberType)
Type EventRegistrationTokenTable`1
Method System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable`1<T> GetOrCreateEventRegistrationTokenTable(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable`1<T>& refEventTable)
Type UnmanagedMemoryAccessor
Method System.Void Write(System.Int64 position, T& structure)
Type AsyncVoidMethodBuilder
Method System.Void Start(TStateMachine& stateMachine)
Method System.Void AwaitOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Method System.Void AwaitUnsafeOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Type AsyncTaskMethodBuilder
Method System.Void Start(TStateMachine& stateMachine)
Method System.Void AwaitOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Method System.Void AwaitUnsafeOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Type AsyncTaskMethodBuilder`1
Method System.Void Start(TStateMachine& stateMachine)
Method System.Void AwaitOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Method System.Void AwaitUnsafeOnCompleted(TAwaiter& awaiter, TStateMachine& stateMachine)
Assembly System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Type EventProvider
Method System.Boolean WriteEvent(System.Diagnostics.Eventing.EventDescriptor& eventDescriptor, System.Object[] eventPayload)
Method System.Boolean WriteEvent(System.Diagnostics.Eventing.EventDescriptor& eventDescriptor, System.String data)
Method System.Boolean WriteTransferEvent(System.Diagnostics.Eventing.EventDescriptor& eventDescriptor, System.Guid relatedActivityId, System.Object[] eventPayload)
Method System.Void SetActivityId(System.Guid& id)
Assembly System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Type IIntellisenseBuilder
Method System.Boolean Show(System.String language, System.String value, System.String& newValue)
Type Executor
Method System.Int32 ExecWaitWithCapture(System.String cmd, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName)
Method System.Int32 ExecWaitWithCapture(System.String cmd, System.String currentDir, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName)
Method System.Int32 ExecWaitWithCapture(System.IntPtr userToken, System.String cmd, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName)
Method System.Int32 ExecWaitWithCapture(System.IntPtr userToken, System.String cmd, System.String currentDir, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName)
Type Uri
Method System.Char HexUnescape(System.String pattern, System.Int32& index)
Type Socket
Method System.Int32 ReceiveMessageFrom(System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags& socketFlags, System.Net.EndPoint& remoteEP, System.Net.Sockets.IPPacketInformation& ipPacketInformation)
Method System.Int32 ReceiveFrom(System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint& remoteEP)
Method System.Int32 ReceiveFrom(System.Byte[] buffer, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint& remoteEP)
Method System.Int32 ReceiveFrom(System.Byte[] buffer, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint& remoteEP)
Method System.Int32 ReceiveFrom(System.Byte[] buffer, System.Net.EndPoint& remoteEP)
Method System.IAsyncResult BeginReceiveMessageFrom(System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint& remoteEP, System.AsyncCallback callback, System.Object state)
Method System.Int32 EndReceiveMessageFrom(System.IAsyncResult asyncResult, System.Net.Sockets.SocketFlags& socketFlags, System.Net.EndPoint& endPoint, System.Net.Sockets.IPPacketInformation& ipPacketInformation)
Method System.IAsyncResult BeginReceiveFrom(System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags, System.Net.EndPoint& remoteEP, System.AsyncCallback callback, System.Object state)
Method System.Int32 EndReceiveFrom(System.IAsyncResult asyncResult, System.Net.EndPoint& endPoint)
Type UdpClient
Method System.Byte[] Receive(System.Net.IPEndPoint& remoteEP)
Method System.Byte[] EndReceive(System.IAsyncResult asyncResult, System.Net.IPEndPoint& remoteEP)
And here is the program:
static void EnumerateMethodsWithRefParameters()
{
foreach (FileInfo file in new DirectoryInfo(RuntimeEnvironment.GetRuntimeDirectory()).GetFiles("*.dll"))
{
AssemblyDefinition asm;
try
{
asm = AssemblyFactory.GetAssembly(file.FullName);
}
catch (ImageFormatException)
{
continue;
}
bool assemblyWritten = false;
foreach (ModuleDefinition module in asm.Modules)
{
foreach (TypeDefinition type in module.Types)
{
if (!ChooseType(type))
continue;
bool typeWritten = false;
foreach (MethodDefinition method in type.Methods)
{
if (!ChooseMethod(method))
continue;
if (!assemblyWritten)
{
Console.WriteLine("Assembly " + asm.Name);
assemblyWritten = true;
}
if (!typeWritten)
{
Console.WriteLine(" Type " + type.Name);
typeWritten = true;
}
Console.WriteLine(" Method " + GetMethodSignature(method));
}
}
}
}
}
static bool ChooseType(TypeDefinition type)
{
if (!type.IsPublic)
return false;
if (IsComRelatedOrObsolete(type))
return false;
return true;
}
static bool ChooseMethod(MethodDefinition method)
{
if (!method.IsPublic)
return false;
foreach (ParameterDefinition parameter in method.Parameters)
{
if ((parameter.ParameterType is ReferenceType) && (!parameter.IsOut))
return true;
}
return false;
}
static bool IsComRelatedOrObsolete(TypeDefinition type)
{
foreach (CustomAttribute att in type.CustomAttributes)
{
if (att.Constructor.DeclaringType.FullName == typeof(ObsoleteAttribute).FullName)
return true;
if (att.Constructor.DeclaringType.FullName == typeof(InterfaceTypeAttribute).FullName)
{
if ((att.Constructor.Parameters.Count > 0) &&
(att.Constructor.Parameters[0].ParameterType.FullName == typeof(ComInterfaceType).FullName))
return true;
}
if (att.Constructor.DeclaringType.FullName == typeof(ComVisibleAttribute).FullName)
return true;
if (att.Constructor.DeclaringType.FullName == typeof(ComConversionLossAttribute).FullName)
return true;
if (att.Constructor.DeclaringType.FullName == typeof(ComImportAttribute).FullName)
return true;
}
return false;
}
static string GetMethodSignature(MethodDefinition method)
{
StringBuilder sb = new StringBuilder(method.ReturnType.ReturnType.FullName);
sb.Append(' ');
sb.Append(method.Name);
sb.Append("(");
for (int i = 0; i < method.Parameters.Count; i++)
{
ParameterDefinition p = method.Parameters[i];
sb.Append(p.ParameterType.FullName);
if (!string.IsNullOrEmpty(p.Name))
{
sb.Append(' ');
sb.Append(p.Name);
}
if (i != (method.Parameters.Count - 1))
{
sb.Append(", ");
}
}
sb.Append(")");
return sb.ToString();
}