2009-10-11 24 views
29

Burada tamamen bir şey eksik olup olmadığından emin değilim, ancak yansıma kullanarak bir parametrenin başvuruda bulunup bulunmadığını belirlemek için bir yol bulamıyorum.Ref Parametreler ve yansıma

ArgumentInfo bir "IsOut" özelliğine sahip, ancak "IsRef" özelliği yok. Belirli bir MethodInfo'da tüm referans parametrelerini almak için nasıl giderim?

+0

de parameterInfo.ParameterType.IsByRef, @Patrik Hägne dikkat eğer sonra bir gerekmeyebilir. IsOut, parametrenin referans olarak geçtiği anlamına da gelmez. Yani, parametrenin bir "çıkış" parametresi olduğu anlamına gelmez. Yakın zamanda keşfettiğim gibi, çok şükürlerime. –

+0

@BlairConrad: Yukarıdaki yorumunuzu detaylandırır mısınız? IsOut hangi durumlarda paramın bir "çıkış" parametresi olduğu anlamına gelmez? – RobSiklos

+0

@RobSiklos, elbette. Sordid öyküsü [FakeItEasy issue 508'deki bir yorum] bölümünde anlatılmıştır (https://github.com/FakeItEasy/FakeItEasy/issues/508#issuecomment-122147155). Bazı parametreler 'Out]' ile dekore edilmiştir. Örneğin, Stream.Read (byte [], int, int) 'deki arabellek. –

cevap

35
ParameterInfo[] parameters = myMethodInfo.GetParameters(); 
foreach(ParameterInfo parameter in parameters) 
{ 
    bool isRef = parameterInfo.ParameterType.IsByRef; 
} 
+2

IsByRef, yalnızca türün bir Referans Türü veya bir tür olduğunu belirttiğim kadar bir Tür olup olmadığını belirler, bu tür referansa göre geçiş yapılıp yapılmadığını size bildirmez. –

+5

Jorge: Anlayabildiğim kadarıyla "IsByRef" belirler Bir tür referans ile iletilirse, bir referans türü değilse. Örneğin, System.Object türü "IsByRef" yanlış, ancak özel bir tür System.Object & "IsByRef true" var. –

+9

Jorge: Ne hakkında konuşuyorsun IsValueType, değil, IsByRef. –

7

daha ileri düzeyde parametresinin türü incelemek gerekir. Örneğin

void Foo(ref int bar) 

sonra parametrenin adı int veya Int32 (beklendiği olabilir gibi) ancak bunun yerine Int32& olmaz varsa. Her tür için, orijinal türün bir '&' ile eklendiği bir yazışma yanlısı türü vardır. Bunu, Type sınıfının IsByRef özelliğiyle kontrol edebilirsiniz.

1

ParametreInfo.ParameterType.IsByRef, parametrenin bildirimi ByRef anahtar sözcüğüyle doğruysa ve bildirimin ByVal anahtar sözcüğüyle olması durumunda false değerini döndürür (parametrenin türünün değere göre olup olmadığına bakılmaksızın) yapı) veya referans (ör., sınıf)).

' Empty structure and class, just for illustration. 
Public Structure MyStruct 
End Structure 

Public Class MyClass1 
End Class 

Ve (siz ByVal alır aşağıdaki yöntemi var ve yukarıda tanımlanan yapı ve sınıf için argümanlar ByRef varsayalım: göstermek için

(I VB kodu kullanıyorum) aşağıdaki yapıyı ve sınıfı dikkate

Public Sub P(s1 As MyStruct, ByRef s2 As MyStruct, c1 As MyClass1, ByRef c2 As MyClass1) 
End Sub 

Şimdi aşağıdaki kod ParameterInfo.ParameterType.IsByRef yöntemini test eder:

varsayılan) olduğu gibi VB 2012 ile başlayarak, ByVal anahtar atlayabilirsiniz unutmayın
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
     ' Reflect on method P: 
    Dim mi As MethodInfo = Me.GetType.GetMethod("P") 
    ' Iterate all parameters, and call its ParameterType.IsByRef method: 
    For Each pi As ParameterInfo In mi.GetParameters 
     If **pi.ParameterType.IsByRef** _ 
     Then Console.WriteLine(pi.Name & " is ByRef") _ 
     Else Console.WriteLine(pi.Name & " is ByVal") 
    Next 
End Sub 

Aşağıdaki çıktıyı alırsınız:, onlar ByRef anahtar sözcüğü ile tanımlanır çünkü

s1 is ByVal 
s2 is ByRef 
c1 is ByVal 
c2 is ByRef 

Gördüğünüz gibi, ParameterInfo.ParameterType.IsByRef argümanlar s2 ve c2 için de geçerlidir döndüren halde bir bunlar bir yapıdır (değer tipi) ve diğeri bir sınıftır (referans tipi); ve ByVal anahtar sözcüğüyle tanımlanan argümanlar için false döndürür. Bununla birlikte, ByVal anahtar sözcüğünün tüm argümanların bir kopya olarak iletileceği anlamına gelmediğini unutmayın. Bu anahtar kelime (ByVal) kullanılsa bile, eğer tür by-reference (ör., Sınıf) ise, argüman ByRef anahtar sözcüğü kullanılmış gibi referans olarak iletilir. Yani, yukarıdaki P metodunun c1 ve c2'si, BOTH referans ile geçirilecektir, yani P bir alanı veya özelliği c1 veya c2 olarak değiştirirse, değişiklikler arayana yansıtılacaktır. (ByVal ve ByRef tipi, bir yapı olarak, bir değer, çoğunlukla fark.)

5

ParameterType.IsByRef hem refveout parametreleri için true döndürür.

ParameterInfo nesnesiniz varsa (ör.Daha sonra,) MethodInfo.GetParameters() den: Eğer out parametreler için IsByRef çek yapmazsanız ref

parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut == false eğer param olduğunu out

  • parameterInfo.ParameterType.IsByRef && parameterInfo.IsOut eğer

    • param o zaman olacak, olan hatalı üye System.Runtime.InteropServices[Out] özniteliği ile süslü olsun ama aslında C# out parametreleri değil.

  • 0

    ref parameterInfo.IsIn == true && parameterInfo.IsOut == true ise tüm

    +0

    Lütfen, backticks kullanın satır içi kodu vurgulayın ve cevabınızı daha okunabilir hale getirmek için düzenleyin (ben cümleyi okuyamıyorum). –