Skip to content

Commit 3cbe67a

Browse files
housekeeping: invert ifs, use TryGetValue, remove unneeded ToArray (#1619)
1 parent 2dff048 commit 3cbe67a

File tree

2 files changed

+125
-135
lines changed

2 files changed

+125
-135
lines changed

Refit/FormValueMultimap.cs

Lines changed: 58 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -48,86 +48,84 @@ public FormValueMultimap(object source, RefitSettings settings)
4848

4949
lock (PropertyCache)
5050
{
51-
if (!PropertyCache.ContainsKey(type))
51+
if (!PropertyCache.TryGetValue(type, out var properties))
5252
{
53-
PropertyCache[type] = GetProperties(type);
53+
properties = GetProperties(type);
54+
PropertyCache[type] = properties;
5455
}
5556

56-
foreach (var property in PropertyCache[type])
57+
foreach (var property in properties)
5758
{
5859
var value = property.GetValue(source, null);
59-
if (value != null)
60+
if (value == null)
61+
continue;
62+
63+
var fieldName = GetFieldNameForProperty(property);
64+
65+
// see if there's a query attribute
66+
var attrib = property.GetCustomAttribute<QueryAttribute>(true);
67+
68+
if (value is not IEnumerable enumerable)
6069
{
61-
var fieldName = GetFieldNameForProperty(property);
70+
Add(
71+
fieldName,
72+
settings.FormUrlEncodedParameterFormatter.Format(value, attrib?.Format)
73+
);
74+
continue;
75+
}
6276

63-
// see if there's a query attribute
64-
var attrib = property.GetCustomAttribute<QueryAttribute>(true);
77+
var collectionFormat =
78+
attrib != null && attrib.IsCollectionFormatSpecified
79+
? attrib.CollectionFormat
80+
: settings.CollectionFormat;
6581

66-
if (value is IEnumerable enumerable)
67-
{
68-
var collectionFormat =
69-
attrib != null && attrib.IsCollectionFormatSpecified
70-
? attrib.CollectionFormat
71-
: settings.CollectionFormat;
82+
switch (collectionFormat)
83+
{
84+
case CollectionFormat.Multi:
85+
foreach (var item in enumerable)
86+
{
87+
Add(
88+
fieldName,
89+
settings.FormUrlEncodedParameterFormatter.Format(
90+
item,
91+
attrib?.Format
92+
)
93+
);
94+
}
7295

73-
switch (collectionFormat)
96+
break;
97+
case CollectionFormat.Csv:
98+
case CollectionFormat.Ssv:
99+
case CollectionFormat.Tsv:
100+
case CollectionFormat.Pipes:
101+
var delimiter = collectionFormat switch
74102
{
75-
case CollectionFormat.Multi:
76-
foreach (var item in enumerable)
77-
{
78-
Add(
79-
fieldName,
80-
settings.FormUrlEncodedParameterFormatter.Format(
81-
item,
82-
attrib?.Format
83-
)
84-
);
85-
}
86-
break;
87-
case CollectionFormat.Csv:
88-
case CollectionFormat.Ssv:
89-
case CollectionFormat.Tsv:
90-
case CollectionFormat.Pipes:
91-
var delimiter = collectionFormat switch
92-
{
93-
CollectionFormat.Csv => ",",
94-
CollectionFormat.Ssv => " ",
95-
CollectionFormat.Tsv => "\t",
96-
_ => "|"
97-
};
98-
99-
var formattedValues = enumerable
100-
.Cast<object>()
101-
.Select(
102-
v =>
103-
settings.FormUrlEncodedParameterFormatter.Format(
104-
v,
105-
attrib?.Format
106-
)
107-
);
108-
Add(fieldName, string.Join(delimiter, formattedValues));
109-
break;
110-
default:
111-
Add(
112-
fieldName,
103+
CollectionFormat.Csv => ",",
104+
CollectionFormat.Ssv => " ",
105+
CollectionFormat.Tsv => "\t",
106+
_ => "|"
107+
};
108+
109+
var formattedValues = enumerable
110+
.Cast<object>()
111+
.Select(
112+
v =>
113113
settings.FormUrlEncodedParameterFormatter.Format(
114-
value,
114+
v,
115115
attrib?.Format
116116
)
117-
);
118-
break;
119-
}
120-
}
121-
else
122-
{
117+
);
118+
Add(fieldName, string.Join(delimiter, formattedValues));
119+
break;
120+
default:
123121
Add(
124122
fieldName,
125123
settings.FormUrlEncodedParameterFormatter.Format(
126124
value,
127125
attrib?.Format
128126
)
129127
);
130-
}
128+
break;
131129
}
132130
}
133131
}

Refit/RequestBuilderImplementation.cs

Lines changed: 67 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public RequestBuilderImplementation(RefitSettings? refitSettings = null)
1616

1717
partial class RequestBuilderImplementation : IRequestBuilder
1818
{
19-
static readonly ISet<HttpMethod> BodylessMethods = new HashSet<HttpMethod>
19+
static readonly HashSet<HttpMethod> BodylessMethods = new HashSet<HttpMethod>
2020
{
2121
HttpMethod.Get,
2222
HttpMethod.Head
@@ -74,16 +74,17 @@ Dictionary<string, List<RestMethodInfoInternal>> methods
7474
{
7575
var attrs = methodInfo.GetCustomAttributes(true);
7676
var hasHttpMethod = attrs.OfType<HttpMethodAttribute>().Any();
77-
if (hasHttpMethod)
78-
{
79-
if (!methods.ContainsKey(methodInfo.Name))
80-
{
81-
methods.Add(methodInfo.Name, new List<RestMethodInfoInternal>());
82-
}
77+
if (!hasHttpMethod)
78+
continue;
8379

84-
var restinfo = new RestMethodInfoInternal(interfaceType, methodInfo, settings);
85-
methods[methodInfo.Name].Add(restinfo);
80+
if (!methods.TryGetValue(methodInfo.Name, out var methodInfoInternals))
81+
{
82+
methodInfoInternals = new List<RestMethodInfoInternal>();
83+
methods.Add(methodInfo.Name, methodInfoInternals);
8684
}
85+
86+
var restinfo = new RestMethodInfoInternal(interfaceType, methodInfo, settings);
87+
methodInfoInternals.Add(restinfo);
8788
}
8889
}
8990

@@ -93,64 +94,62 @@ RestMethodInfoInternal FindMatchingRestMethodInfo(
9394
Type[]? genericArgumentTypes
9495
)
9596
{
96-
if (interfaceHttpMethods.TryGetValue(key, out var httpMethods))
97+
if (!interfaceHttpMethods.TryGetValue(key, out var httpMethods))
98+
{
99+
throw new ArgumentException(
100+
"Method must be defined and have an HTTP Method attribute"
101+
);
102+
}
103+
104+
if (parameterTypes == null)
97105
{
98-
if (parameterTypes == null)
106+
if (httpMethods.Count > 1)
99107
{
100-
if (httpMethods.Count > 1)
101-
{
102-
throw new ArgumentException(
103-
$"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined"
104-
);
105-
}
106-
return CloseGenericMethodIfNeeded(httpMethods[0], genericArgumentTypes);
108+
throw new ArgumentException(
109+
$"MethodName exists more than once, '{nameof(parameterTypes)}' mut be defined"
110+
);
107111
}
108112

109-
var isGeneric = genericArgumentTypes?.Length > 0;
113+
return CloseGenericMethodIfNeeded(httpMethods[0], genericArgumentTypes);
114+
}
110115

111-
var possibleMethodsList = httpMethods.Where(
112-
method => method.MethodInfo.GetParameters().Length == parameterTypes.Length
113-
);
116+
var isGeneric = genericArgumentTypes?.Length > 0;
114117

115-
// If it's a generic method, add that filter
116-
if (isGeneric)
117-
possibleMethodsList = possibleMethodsList.Where(
118-
method =>
119-
method.MethodInfo.IsGenericMethod
120-
&& method.MethodInfo.GetGenericArguments().Length
121-
== genericArgumentTypes!.Length
122-
);
123-
else // exclude generic methods
124-
possibleMethodsList = possibleMethodsList.Where(
125-
method => !method.MethodInfo.IsGenericMethod
126-
);
118+
var possibleMethodsList = httpMethods.Where(
119+
method => method.MethodInfo.GetParameters().Length == parameterTypes.Length
120+
);
127121

128-
var possibleMethods = possibleMethodsList.ToList();
122+
// If it's a generic method, add that filter
123+
if (isGeneric)
124+
possibleMethodsList = possibleMethodsList.Where(
125+
method =>
126+
method.MethodInfo.IsGenericMethod
127+
&& method.MethodInfo.GetGenericArguments().Length
128+
== genericArgumentTypes!.Length
129+
);
130+
else // exclude generic methods
131+
possibleMethodsList = possibleMethodsList.Where(
132+
method => !method.MethodInfo.IsGenericMethod
133+
);
129134

130-
if (possibleMethods.Count == 1)
131-
return CloseGenericMethodIfNeeded(possibleMethods[0], genericArgumentTypes);
135+
var possibleMethods = possibleMethodsList.ToList();
132136

133-
var parameterTypesArray = parameterTypes.ToArray();
134-
foreach (var method in possibleMethods)
135-
{
136-
var match = method.MethodInfo
137-
.GetParameters()
138-
.Select(p => p.ParameterType)
139-
.SequenceEqual(parameterTypesArray);
140-
if (match)
141-
{
142-
return CloseGenericMethodIfNeeded(method, genericArgumentTypes);
143-
}
144-
}
137+
if (possibleMethods.Count == 1)
138+
return CloseGenericMethodIfNeeded(possibleMethods[0], genericArgumentTypes);
145139

146-
throw new Exception("No suitable Method found...");
147-
}
148-
else
140+
foreach (var method in possibleMethods)
149141
{
150-
throw new ArgumentException(
151-
"Method must be defined and have an HTTP Method attribute"
152-
);
142+
var match = method.MethodInfo
143+
.GetParameters()
144+
.Select(p => p.ParameterType)
145+
.SequenceEqual(parameterTypes);
146+
if (match)
147+
{
148+
return CloseGenericMethodIfNeeded(method, genericArgumentTypes);
149+
}
153150
}
151+
152+
throw new Exception("No suitable Method found...");
154153
}
155154

156155
RestMethodInfoInternal CloseGenericMethodIfNeeded(
@@ -487,19 +486,12 @@ CancellationToken cancellationToken
487486
if (obj == null)
488487
continue;
489488

490-
if (parameterInfo != null)
489+
//if we have a parameter info lets check it to make sure it isn't bound to the path
490+
if (parameterInfo is { IsObjectPropertyParameter: true })
491491
{
492-
//if we have a parameter info lets check it to make sure it isn't bound to the path
493-
if (parameterInfo.IsObjectPropertyParameter)
492+
if (parameterInfo.ParameterProperties.Any(x => x.PropertyInfo == propertyInfo))
494493
{
495-
if (
496-
parameterInfo.ParameterProperties.Any(
497-
x => x.PropertyInfo == propertyInfo
498-
)
499-
)
500-
{
501-
continue;
502-
}
494+
continue;
503495
}
504496
}
505497

@@ -511,7 +503,7 @@ CancellationToken cancellationToken
511503

512504
// Look to see if the property has a Query attribute, and if so, format it accordingly
513505
var queryAttribute = propertyInfo.GetCustomAttribute<QueryAttribute>();
514-
if (queryAttribute != null && queryAttribute.Format != null)
506+
if (queryAttribute is { Format: not null })
515507
{
516508
obj = settings.FormUrlEncodedParameterFormatter.Format(
517509
obj,
@@ -657,9 +649,9 @@ bool paramsContainsCancellationToken
657649
var isParameterMappedToRequest = false;
658650
var param = paramList[i];
659651
// if part of REST resource URL, substitute it in
660-
if (restMethod.ParameterMap.ContainsKey(i))
652+
if (restMethod.ParameterMap.TryGetValue(i, out var parameterMapValue))
661653
{
662-
parameterInfo = restMethod.ParameterMap[i];
654+
parameterInfo = parameterMapValue;
663655
if (parameterInfo.IsObjectPropertyParameter)
664656
{
665657
foreach (var propertyInfo in parameterInfo.ParameterProperties)
@@ -684,9 +676,9 @@ bool paramsContainsCancellationToken
684676
{
685677
string pattern;
686678
string replacement;
687-
if (restMethod.ParameterMap[i].Type == ParameterType.RoundTripping)
679+
if (parameterMapValue.Type == ParameterType.RoundTripping)
688680
{
689-
pattern = $@"{{\*\*{restMethod.ParameterMap[i].Name}}}";
681+
pattern = $@"{{\*\*{parameterMapValue.Name}}}";
690682
var paramValue = (string)param;
691683
replacement = string.Join(
692684
"/",
@@ -706,7 +698,7 @@ bool paramsContainsCancellationToken
706698
}
707699
else
708700
{
709-
pattern = "{" + restMethod.ParameterMap[i].Name + "}";
701+
pattern = "{" + parameterMapValue.Name + "}";
710702
replacement = Uri.EscapeDataString(
711703
settings.UrlParameterFormatter.Format(
712704
param,
@@ -802,9 +794,9 @@ await content
802794
}
803795

804796
// if header, add to request headers
805-
if (restMethod.HeaderParameterMap.ContainsKey(i))
797+
if (restMethod.HeaderParameterMap.TryGetValue(i, out var headerParameterValue))
806798
{
807-
headersToAdd[restMethod.HeaderParameterMap[i]] = param?.ToString();
799+
headersToAdd[headerParameterValue] = param?.ToString();
808800
isParameterMappedToRequest = true;
809801
}
810802

@@ -1000,7 +992,7 @@ param as IDictionary<string, string>
1000992
}
1001993
}
1002994

1003-
if (queryParamsToAdd.Any())
995+
if (queryParamsToAdd.Count != 0)
1004996
{
1005997
var pairs = queryParamsToAdd
1006998
.Where(x => x.Key != null && x.Value != null)

0 commit comments

Comments
 (0)