Skip to content

Commit 876d43e

Browse files
authored
Merge pull request #260 from DataObjects-NET/attributes-extraction-improvement
No copies of collection on attributes extraction
2 parents 84e4ba4 + 883df07 commit 876d43e

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

Orm/Xtensive.Orm/Reflection/AttributeHelper.cs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2008-2021 Xtensive LLC.
1+
// Copyright (C) 2008-2022 Xtensive LLC.
22
// This code is distributed under MIT license terms.
33
// See the License.txt file in the project root for more information.
44
// Created by: Alex Yakunin
@@ -11,6 +11,7 @@
1111
using System.Reflection;
1212
using AttributesKey = System.ValueTuple<System.Reflection.MemberInfo, System.Type, Xtensive.Reflection.AttributeSearchOptions>;
1313
using PerAttributeKey = System.ValueTuple<System.Reflection.MemberInfo, Xtensive.Reflection.AttributeSearchOptions>;
14+
using Xtensive.Core;
1415

1516
namespace Xtensive.Reflection
1617
{
@@ -71,43 +72,60 @@ public static TAttribute GetAttribute<TAttribute>(this MemberInfo member, Attrib
7172
private static IReadOnlyList<Attribute> GetAttributes(MemberInfo member, Type attributeType, AttributeSearchOptions options) =>
7273
attributesByMemberInfoAndSearchOptions.GetOrAdd(
7374
new AttributesKey(member, attributeType, options),
74-
t => ExtractAttributes(t).ToArray()
75+
t => ExtractAttributes(t, out var count).ToArray(count)
7576
);
7677

77-
private static Attribute[] GetAttributes(this MemberInfo member, Type attributeType)
78+
private static IEnumerable<Attribute> GetAttributes(this MemberInfo member, Type attributeType, out int count)
7879
{
7980
var attrObjects = member.GetCustomAttributes(attributeType, false);
80-
var attrs = new Attribute[attrObjects.Length];
81-
for (int i = attrObjects.Length; i-- > 0;) {
82-
attrs[i] = (Attribute) attrObjects[i];
83-
}
84-
return attrs;
81+
count = attrObjects.Length;
82+
return (count == 0)
83+
? Array.Empty<Attribute>()
84+
: attrObjects.Cast<Attribute>();
8585
}
8686

87-
private static IEnumerable<Attribute> ExtractAttributes((MemberInfo member, Type attributeType, AttributeSearchOptions options) t) {
87+
private static IEnumerable<Attribute> ExtractAttributes((MemberInfo member, Type attributeType, AttributeSearchOptions options) t, out int count)
88+
{
8889
(var member, var attributeType, var options) = t;
8990

90-
var attributes = member.GetCustomAttributes(attributeType, false).Cast<Attribute>().ToList();
91-
if (options == AttributeSearchOptions.InheritNone)
92-
return attributes;
93-
if (attributes.Count == 0) {
91+
var customAttributesRaw = member.GetCustomAttributes(attributeType, false);
92+
count = customAttributesRaw.Length;
93+
94+
if (options == AttributeSearchOptions.InheritNone) {
95+
return (customAttributesRaw.Length == 0)
96+
? Array.Empty<Attribute>()
97+
: customAttributesRaw.Cast<Attribute>();
98+
}
99+
100+
IEnumerable<Attribute> attributes;
101+
if (customAttributesRaw.Length == 0) {
102+
attributes = Enumerable.Empty<Attribute>();
94103
if ((options & AttributeSearchOptions.InheritFromPropertyOrEvent) != 0
95104
&& member is MethodInfo m
96105
&& ((MemberInfo) m.GetProperty() ?? m.GetEvent()) is MemberInfo poe) {
97-
attributes = poe.GetAttributes(attributeType).ToList();
106+
var poeAttributes = poe.GetAttributes(attributeType, out var count1);
107+
count = count1;
108+
attributes = poeAttributes;
98109
}
99110
if ((options & AttributeSearchOptions.InheritFromBase) != 0
100111
&& (options & AttributeSearchOptions.InheritRecursively) == 0
101112
&& member.GetBaseMember() is MemberInfo bm) {
102-
attributes.AddRange(GetAttributes(bm, attributeType, options));
113+
var inheritedAttributes = GetAttributes(bm, attributeType, options);
114+
count += inheritedAttributes.Count;
115+
attributes = attributes.Concat(inheritedAttributes);
103116
return attributes;
104117
}
105118
}
119+
else {
120+
attributes = customAttributesRaw.Cast<Attribute>();
121+
}
106122

107123
if ((options & AttributeSearchOptions.InheritFromAllBase) == AttributeSearchOptions.InheritFromAllBase
108124
&& member.DeclaringType != WellKnownTypes.Object
109125
&& member.GetBaseMember() is MemberInfo bm2) {
110-
attributes.AddRange(GetAttributes(bm2, attributeType, options));
126+
var inheritedAttributes = GetAttributes(bm2, attributeType, options);
127+
count += inheritedAttributes.Count;
128+
attributes = attributes.Concat(inheritedAttributes);
111129
}
112130

113131
return attributes;

Orm/Xtensive.Orm/Reflection/AttributeSearchOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ public enum AttributeSearchOptions
4444
/// <summary>
4545
/// All inheritance options.
4646
/// </summary>
47-
InheritAll = 7,
47+
InheritAll = InheritFromBase | InheritRecursively | InheritFromPropertyOrEvent,
4848
}
4949
}

0 commit comments

Comments
 (0)