I am not understanding how this compiles.
I have a VB.net class with the following:
Public Class Line
Public Enum EligibleType
skipNone = 0
skipAllow = 1
skipPay = 2
skipDeleted = 4
skipMod = 8
skipOverride = 16
End Enum
Public Function Eligible(Optional ByRef enmEligibleFlag As Line.EligibleType = Line.EligibleType.brSkipNone) As Boolean
End Class
This is called over 9,000 times in the application. I tried to write a test method in C# for another function and used Rhino Mocks to create a stub of the class. Then I stubbed the function to always return true. It would not compile.
[TestClass]
public class breMATest
{
/// <summary>
/// Tests the 102.
/// </summary>
[TestMethod]
public void Test102()
{
// Arrange
br target = new br();
var line = MockRepository.GenerateStub<Line>();
line.Stub(s => s.Eligible(ref Arg<Line.EligibleType>.Ref(brBD.Line.EligibleType, Line.EligibleType.skipNone).Dummy).Return(true);
// Act
target.Pay102(ref line);
// Assert
}
}
This gives me:
CS1510: A ref or out argument must be an assignable variable
UnitTestsCS\brTest.cs(35,13,35,71): error CS1502: The best overloaded method match for 'brBD.Line.Eligible(ref brBD.Line.EligibleType)' has some invalid arguments
I tried this as well, with the same results:
line.Stub(s => s.Eligible(brBD.Line.EligibleType.skipNone)).Return(true);
I tried calling it directly, same error:
line.Eligible(ref brBD.Line.EligibleType.skipNone));
I understand the error. You can’t pass an enumeration by reference because an enumeration is a constant and can’t be assigned. So I have two questions:
Thanks in advance,
Tim
The thing you are passing as ref
is:
Arg<Line.EligibleType>
.Ref(brBD.Line.EligibleType, Line.EligibleType.skipNone).Dummy
Now; we can't see Arg<T>.Ref
, but I'm guessing it returns a class upon which .Dummy
is a property. In C# you can't pass a property as a ref
. I imagine VB elects to spoof this, essentially doing the equivalent of:
var tmp = Arg<Line.EligibleType>.Ref(brBD.Line.EligibleType, Line.EligibleType.skipNone).Dummy;
return s.Eligible(ref tmp)
However, C# chooses not to work this way. IIRC, VB also allows ref
to be implicit, so there are some very different design aims around how ref
should be treated.
But I have to agree with C# - in the ref
usage, you aren't really passing a "reference to the property", so for me at least, it avoids incorrect usage to work the way it does - even if that is more explicit.
As an aside: if .Dummy
was a field, then you can pass it as ref
; however, this should not be interpreted as "make .Dummy
a field"; that is very much not what I said ;p
I understand the error. You can’t pass an enumeration by reference because an enumeration is a constant and can’t be assigned.
You can pass references to fields, references to local variables / parameters, and references to things in array as ref
; those things can be typed as enumerations.