C
C#2mo ago
nullpointer

I have trouble with using dynamic returns on nuget package

I have a build a asembly with a public method public static dynamic AssertThat(object? current), it returns specific assert implementations based on the object type. It works perfect on project using ProjectReference but fails when using PackageReference The error is
'object' does not contain a definition for 'IsTrue'
at CallSite.Target(Closure, CallSite, Object)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at GdUnit4.Tests.Asserts.CSharpTypes.AssertThatCoverageTest.AssertThatCoverageTestOnBool() in D:\development\workspace\gdUnit4Net\Example\test\api\AssertThatCoverageTest.cs:line 20
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
'object' does not contain a definition for 'IsTrue'
at CallSite.Target(Closure, CallSite, Object)
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at GdUnit4.Tests.Asserts.CSharpTypes.AssertThatCoverageTest.AssertThatCoverageTestOnBool() in D:\development\workspace\gdUnit4Net\Example\test\api\AssertThatCoverageTest.cs:line 20
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
What goes wrong?
1 Reply
nullpointer
nullpointerOP2mo ago
here the test
[TestCase]
public void AssertThatCoverageTestOnBool()
{
var boolAssert = AssertThat(true as object);
var type = boolAssert.GetType();
Console.WriteLine(type);
foreach (var method in type.GetMethods())
Console.WriteLine($" {method.ReturnType} {method.Name}( {method.GetParameters()})) ");

boolAssert.IsTrue();
}
[TestCase]
public void AssertThatCoverageTestOnBool()
{
var boolAssert = AssertThat(true as object);
var type = boolAssert.GetType();
Console.WriteLine(type);
foreach (var method in type.GetMethods())
Console.WriteLine($" {method.ReturnType} {method.Name}( {method.GetParameters()})) ");

boolAssert.IsTrue();
}
shows
GdUnit4.Asserts.BoolAssert
GdUnit4.Constraints.IBoolConstraint IsFalse( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsTrue( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsEqual( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNotEqual( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNull( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNotNull( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint OverrideFailureMessage( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint AppendFailureMessage( System.Reflection.ParameterInfo[]))
System.Type GetType( System.Reflection.ParameterInfo[]))
System.String ToString( System.Reflection.ParameterInfo[]))
System.Boolean Equals( System.Reflection.ParameterInfo[]))
System.Int32 GetHashCode( System.Reflection.ParameterInfo[]))
GdUnit4.Asserts.BoolAssert
GdUnit4.Constraints.IBoolConstraint IsFalse( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsTrue( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsEqual( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNotEqual( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNull( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint IsNotNull( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint OverrideFailureMessage( System.Reflection.ParameterInfo[]))
GdUnit4.Constraints.IBoolConstraint AppendFailureMessage( System.Reflection.ParameterInfo[]))
System.Type GetType( System.Reflection.ParameterInfo[]))
System.String ToString( System.Reflection.ParameterInfo[]))
System.Boolean Equals( System.Reflection.ParameterInfo[]))
System.Int32 GetHashCode( System.Reflection.ParameterInfo[]))
So the method IsTrue exists. When i change the first line to var boolAssert = AssertThat(true as object) as IBoolAssert; the same output is shown but the test succeeds the API method
public static dynamic AssertThat(object? current)
=> current switch
{
bool v => AssertThat(v),
string v => AssertThat(v),
sbyte v => AssertThat(v),
byte v => AssertThat(v),
short v => AssertThat(v),
ushort v => AssertThat(v),
int v => AssertThat(v),
uint v => AssertThat(v),
long v => AssertThat(v),
ulong v => AssertThat(v),
float v => AssertThat(v),
double v => AssertThat(v),
decimal v => AssertThat(v),
_ => AssertObject(current.UnboxVariant())
};
public static dynamic AssertThat(object? current)
=> current switch
{
bool v => AssertThat(v),
string v => AssertThat(v),
sbyte v => AssertThat(v),
byte v => AssertThat(v),
short v => AssertThat(v),
ushort v => AssertThat(v),
int v => AssertThat(v),
uint v => AssertThat(v),
long v => AssertThat(v),
ulong v => AssertThat(v),
float v => AssertThat(v),
double v => AssertThat(v),
decimal v => AssertThat(v),
_ => AssertObject(current.UnboxVariant())
};
It retruning based on the parameter an instance of BoolAssert, StringAssert, ObjectAssert, ... i found the issue, the implementation classes was not public only the interfaces.

Did you find this page helpful?