Skip to content

Commit

Permalink
Ducktype instance type check (#6373)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyredondo authored Nov 28, 2024
1 parent 959f006 commit 7f5fb56
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
6 changes: 3 additions & 3 deletions tracer/src/Datadog.Trace/DuckTyping/DuckType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1350,7 +1350,7 @@ public static CreateTypeResult GetProxy(Type targetType)
return default;
}

return GetProxy(instance.GetType()).CreateInstance<T>(instance);
return instance is T tInst ? tInst : GetProxy(instance.GetType()).CreateInstance<T>(instance);
}

/// <summary>
Expand All @@ -1368,7 +1368,7 @@ public static CreateTypeResult GetProxy(Type targetType)
return default;
}

return GetProxy(typeof(TOriginal)).CreateInstance<T, TOriginal>(instance);
return instance is T tInst ? tInst : GetProxy(typeof(TOriginal)).CreateInstance<T, TOriginal>(instance);
}

/// <summary>
Expand All @@ -1384,7 +1384,7 @@ public static bool CanCreate(object? instance)
return false;
}

return GetProxy(instance.GetType()).CanCreate();
return instance is T || GetProxy(instance.GetType()).CanCreate();
}

/// <summary>
Expand Down
42 changes: 35 additions & 7 deletions tracer/src/Datadog.Trace/DuckTyping/DuckTypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public static object DuckCast(this object instance, Type targetType)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryDuckCast<T>(this object? instance, [NotNullWhen(true)] out T? value)
{
if (instance is T tInst)
{
value = tInst;
return true;
}

if (instance is not null &&
DuckType.CreateCache<T>.GetProxy(instance.GetType()) is { Success: true } proxyResult)
{
Expand All @@ -71,11 +77,20 @@ public static bool TryDuckCast(this object? instance, Type targetType, [NotNullW
{
if (targetType is null) { ThrowHelper.ThrowArgumentNullException(nameof(targetType)); }

if (instance is not null &&
DuckType.GetOrCreateProxyType(targetType, instance.GetType()) is { Success: true } proxyResult)
if (instance is not null)
{
value = proxyResult.CreateInstance(instance);
return true;
var instanceType = instance.GetType();
if (instanceType == targetType)
{
value = instance;
return true;
}

if (DuckType.GetOrCreateProxyType(targetType, instanceType) is { Success: true } proxyResult)
{
value = proxyResult.CreateInstance(instance);
return true;
}
}

value = default;
Expand All @@ -92,6 +107,11 @@ public static bool TryDuckCast(this object? instance, Type targetType, [NotNullW
public static T? DuckAs<T>(this object? instance)
where T : class
{
if (instance is T tInst)
{
return tInst;
}

if (instance is not null &&
DuckType.CreateCache<T>.GetProxy(instance.GetType()) is { Success: true } proxyResult)
{
Expand All @@ -112,10 +132,18 @@ public static bool TryDuckCast(this object? instance, Type targetType, [NotNullW
{
if (targetType is null) { ThrowHelper.ThrowArgumentNullException(nameof(targetType)); }

if (instance is not null &&
DuckType.GetOrCreateProxyType(targetType, instance.GetType()) is { Success: true } proxyResult)
if (instance is not null)
{
return proxyResult.CreateInstance(instance);
var instanceType = instance.GetType();
if (instanceType == targetType)
{
return instance;
}

if (DuckType.GetOrCreateProxyType(targetType, instanceType) is { Success: true } proxyResult)
{
return proxyResult.CreateInstance(instance);
}
}

return null;
Expand Down

0 comments on commit 7f5fb56

Please sign in to comment.