.NET framework library ref keyword example

DateTime.TryParse

has a parameter DateTime

out

.

public static bool TryParse(string s, out DateTime result)

      

Is there such use of the keyword ref

in the .NET framework?

+3


source to share


5 answers


Yes, for example various overloads Interlocked.Exchange

:



public static double Exchange(
ref double location1,
double value
)

      

+7


source


This is used in various places. For example, XNA uses heavily ref

in methods like Matrix.Add for performance reasons. Many of the blocked methods rely on ref

to work properly.



That being said, ref

it is something to be used sparingly, according to the design guide for class libraries, which is partly because it is not very common. There is even a code analysis warning (CA1045) that suggests not using it ref

, although there are reasons to suppress this sometimes.

+5


source


You can list all the methods ref

in mscorlib using reflection (and LINQ):

from type in typeof(object).Assembly.GetExportedTypes()
where !type.IsInterface
from method in type.GetMethods()
where method.GetParameters().Any(
    p => p.ParameterType.IsByRef &&
        !p.GetCustomAttributes(typeof(OutAttribute), false).Any())
select method

      

You need filtering methods that have a ref

c parameter OutAttribute

because parameters are actually represented out

.

+5


source


Actually, I was curious, so I wrote a small program that scans .NET Framework assemblies and unloads public methods that contain at least one ref parameter. It uses mono cecil's static reflection capabilities.

It discards Obsolete

and COM

-related methods (which have many ref parameters due to their nature).

Here is the output 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's 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();
}

      

+1


source


DateTime dte;
if (DateTime.TryParse("date text", out dte))
{
    // Parse succeeded dte has the value
}

      

-2


source







All Articles