Skip to content

Commit 00642c9

Browse files
authored
Merge pull request #668 from stakx/enhancement/nullable-reference-type-annotations
Add nullable reference type annotations to DynamicProxy's public API
2 parents 3374796 + 7122b6c commit 00642c9

32 files changed

+824
-720
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Enhancements:
66
- Two new generic method overloads `proxyGenerator.CreateClassProxy<TClass>([options], constructorArguments, interceptors)` (@backstromjoel, #636)
77
- Allow specifying which attributes should always be copied to proxy class by adding attribute type to `AttributesToAlwaysReplicate`. Previously only non-inherited, with `Inherited=false`, attributes were copied. (@shoaibshakeel381, #633)
88
- Support for C# 8+ [default interface methods](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods) in interface and class proxies without target (@stakx, #661)
9+
- DynamicProxy's public API has been augmented with nullable reference type annotations (@stakx, #668)
910

1011
Bugfixes:
1112
- `ArgumentException`: "Could not find method overriding method" with overridden class method having generic by-ref parameter (@stakx, #657)

ref/Castle.Core-net462.cs

Lines changed: 129 additions & 128 deletions
Large diffs are not rendered by default.

ref/Castle.Core-net6.0.cs

Lines changed: 125 additions & 123 deletions
Large diffs are not rendered by default.

ref/Castle.Core-netstandard2.0.cs

Lines changed: 124 additions & 123 deletions
Large diffs are not rendered by default.

ref/Castle.Core-netstandard2.1.cs

Lines changed: 124 additions & 123 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2004-2023 Castle Project - http://www.castleproject.org/
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace System.Diagnostics.CodeAnalysis
16+
{
17+
using System;
18+
19+
#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP3_0_OR_GREATER
20+
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
21+
internal sealed class DoesNotReturnAttribute : Attribute
22+
{
23+
}
24+
#endif
25+
26+
#if !NET5_0_OR_GREATER
27+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
28+
internal sealed class MemberNotNullAttribute : Attribute
29+
{
30+
public MemberNotNullAttribute(string member)
31+
{
32+
Members = new[] { member };
33+
}
34+
35+
public string[] Members { get; }
36+
}
37+
#endif
38+
39+
#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP3_0_OR_GREATER
40+
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
41+
internal sealed class NotNullWhenAttribute : Attribute
42+
{
43+
public NotNullWhenAttribute(bool returnValue)
44+
{
45+
ReturnValue = returnValue;
46+
}
47+
48+
public bool ReturnValue { get; }
49+
}
50+
#endif
51+
}

src/Castle.Core/DynamicProxy/AbstractInvocation.cs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,30 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#nullable enable
16+
1517
namespace Castle.DynamicProxy
1618
{
1719
using System;
1820
using System.Diagnostics;
21+
using System.Diagnostics.CodeAnalysis;
1922
using System.Reflection;
2023

2124
public abstract class AbstractInvocation : IInvocation
2225
{
2326
private readonly IInterceptor[] interceptors;
24-
private readonly object[] arguments;
27+
private readonly object?[] arguments;
2528
private int currentInterceptorIndex = -1;
26-
private Type[] genericMethodArguments;
29+
private Type[]? genericMethodArguments;
2730
private readonly MethodInfo proxiedMethod;
2831
protected readonly object proxyObject;
2932

3033
protected AbstractInvocation(
3134
object proxy,
3235
IInterceptor[] interceptors,
3336
MethodInfo proxiedMethod,
34-
object[] arguments)
37+
object?[] arguments)
3538
{
36-
Debug.Assert(proxiedMethod != null);
3739
proxyObject = proxy;
3840
this.interceptors = interceptors;
3941
this.proxiedMethod = proxiedMethod;
@@ -45,13 +47,13 @@ public void SetGenericMethodArguments(Type[] arguments)
4547
genericMethodArguments = arguments;
4648
}
4749

48-
public abstract object InvocationTarget { get; }
50+
public abstract object? InvocationTarget { get; }
4951

50-
public abstract Type TargetType { get; }
52+
public abstract Type? TargetType { get; }
5153

52-
public abstract MethodInfo MethodInvocationTarget { get; }
54+
public abstract MethodInfo? MethodInvocationTarget { get; }
5355

54-
public Type[] GenericArguments
56+
public Type[]? GenericArguments
5557
{
5658
get { return genericMethodArguments; }
5759
}
@@ -71,7 +73,7 @@ public MethodInfo GetConcreteMethod()
7173
return EnsureClosedMethod(Method);
7274
}
7375

74-
public MethodInfo GetConcreteMethodInvocationTarget()
76+
public MethodInfo? GetConcreteMethodInvocationTarget()
7577
{
7678
// it is ensured by the InvocationHelper that method will be closed
7779
var method = MethodInvocationTarget;
@@ -80,19 +82,19 @@ public MethodInfo GetConcreteMethodInvocationTarget()
8082
return method;
8183
}
8284

83-
public object ReturnValue { get; set; }
85+
public object? ReturnValue { get; set; }
8486

85-
public object[] Arguments
87+
public object?[] Arguments
8688
{
8789
get { return arguments; }
8890
}
8991

90-
public void SetArgumentValue(int index, object value)
92+
public void SetArgumentValue(int index, object? value)
9193
{
9294
arguments[index] = value;
9395
}
9496

95-
public object GetArgumentValue(int index)
97+
public object? GetArgumentValue(int index)
9698
{
9799
return arguments[index];
98100
}
@@ -137,6 +139,7 @@ public IInvocationProceedInfo CaptureProceedInfo()
137139

138140
protected abstract void InvokeMethodOnTarget();
139141

142+
[DoesNotReturn]
140143
protected void ThrowOnNoTarget()
141144
{
142145
// let's try to build as friendly message as we can
@@ -152,7 +155,7 @@ protected void ThrowOnNoTarget()
152155

153156
string methodKindIs;
154157
string methodKindDescription;
155-
if (Method.DeclaringType.IsClass && Method.IsAbstract)
158+
if (Method.DeclaringType!.IsClass && Method.IsAbstract)
156159
{
157160
methodKindIs = "is abstract";
158161
methodKindDescription = "an abstract method";

src/Castle.Core/DynamicProxy/AllMethodsHook.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
#nullable enable
16+
1517
namespace Castle.DynamicProxy
1618
{
1719
using System;
@@ -32,7 +34,7 @@ public class AllMethodsHook : IProxyGenerationHook
3234

3335
public virtual bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
3436
{
35-
return SkippedTypes.Contains(methodInfo.DeclaringType) == false;
37+
return SkippedTypes.Contains(methodInfo.DeclaringType!) == false;
3638
}
3739

3840
public virtual void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
@@ -43,7 +45,7 @@ public virtual void MethodsInspected()
4345
{
4446
}
4547

46-
public override bool Equals(object obj)
48+
public override bool Equals(object? obj)
4749
{
4850
return obj != null && obj.GetType() == GetType();
4951
}

0 commit comments

Comments
 (0)