DateTime.TryParse
方法有一个DateTime
out
参数。
public static bool TryParse(string s, out DateTime result)
ref
.NET 框架中是否有这样的关键字用法?
是的,例如各种重载Interlocked.Exchange
:
public static double Exchange(
ref double location1,
double value
)
这用于不同的位置。例如,出于性能原因,XNAref
在诸如Matrix.Add 之类的方法中大量使用。许多互锁方法依赖于ref
正确操作。
话虽ref
如此,根据类库的设计指南,应该谨慎使用,这也是它不是很常见的部分原因。甚至还有一个代码分析警告 (CA1045)建议不要使用ref
,尽管有时有理由不使用它。
您可以ref
使用反射(和 LINQ)获取 mscorlib 中所有方法的列表:
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
过滤掉带有ref
参数的方法OutAttribute
是必要的,因为这就是out
参数的实际表示方式。
实际上,我自己也很好奇,所以我编写了一个小程序来扫描 .NET Framework 程序集并转储出至少具有一个 ref 参数的公共方法。它使用单 cecil静态反射功能。
它丢弃Obsolete
和COM
相关的方法(由于它们的性质而具有很多 ref 参数)。
下面是 mscorlib、system 和 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)
这是程序:
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();
}
DateTime dte;
if (DateTime.TryParse("date text", out dte))
{
// Parse succeeded dte has the value
}