2012-03-26 12 views
6

Uzun bir başlık, ancak belirli olmasını istedim. Başlık gerçekten soru. InvokeMember'un çağırdığı yöntemde bir out parametresi olsa ve bu değere bir değer atayarak bu değeri alamıyorum. İşte başlangıçta kullanıyordum kodudur:Neden Type.InvokeMember? Kullanarak türünü veya ref parametrelerini almak için değeri alamıyorum?

string parameter = ""; 
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, new object[] { parameter })); 

ben amaçlanan ama bilmiyorum artık o iş yapar bu, neden değiştirdiğini:

object[] args = new object[1];  //necessary to retrieve ref/out parameter 
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args)); 

cevap

3

ilk kod örneğinde, InvokeMember çağrısı, parameter değişkeninin değerini değiştirmez, yalnızca parametre dizisindeki ilk öğenin yerini alır (artık farklı bir string örneğini işaret eder). Bu diziye referans göstermediğiniz için, çıkış parametresinin değerini alamazsınız. Başka bir deyişle: dizi başlangıçta parameter değişkeninin bir kopyasını içerir (yani referansın boş bir dizeye kopyalanması). Aramadan sonra, parameter ve dizideki değer 2 farklı dize örneğine başvurur.

5

İkinci kod parçanızın oldukça önemli bir kod satırı eksik.

object[] args = new object[1];  //necessary to retrieve ref/out parameter 
int result = Convert.ToInt32(typeof(Ability).InvokeMember(selectedMove, 
    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, 
    null, null, args)); 
string outValue = (string)args[0]; // <=== here! 

O artık ayrıca 1 pasajı çalışamaz neden açık olmalı, nesne [] dizisine bir başvuru yok: Bu üzerinden argüman dize türünde olduğunu varsayarak, bu gibi görünmelidir Geçtiğinizde, değiştirilen argümanı asla geri alamazsınız.

6

Sadece yönetilmeyen (COM) ile mücadele eden (geri) ve yeniden parametrelendirme yapan birine yardım etmek istedim. Bu nedenle, COM-yöntemine karşı InvokeMember kullanırken, hangi argümanların tür olduğunu belirtmelisiniz. Bu Örneğin, ParameterModifier-sınıfı kullanılarak elde edilir:

Yukarıdaki 3. bağımsız değişken bir referans olacak şekilde ayarlanır kodda
object[] args = new object[3] { param1, param2, errorStr }; 
ParameterModifier pMod = new ParameterModifier(3); 
pMod[2] = true;    
ParameterModifier[] mods = { pMod }; 

object tempObj = myCOMObject.GetType().InvokeMember("MyCOMMethod", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public, null, myCOMObject, args, mods, null, null); 

(PMOD [2] = true;)

+0

vay ... Bu sadece beni kurtardı teşekkürler. –

İlgili konular