Skip to content

Commit

Permalink
Metadata: Disallow backing field on indexer property
Browse files Browse the repository at this point in the history
- Don't discover backing field for indexer property by convention
- Throw if trying to set a backing field for indexer property

Resolves #19448
  • Loading branch information
smitpatel committed Jan 1, 2020
1 parent ddf496f commit a8072e9
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/EFCore/Metadata/Conventions/BackingFieldConvention.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public virtual void ProcessNavigationAdded(
private FieldInfo GetFieldToSet(IConventionPropertyBase propertyBase)
{
if (propertyBase == null
|| !ConfigurationSource.Convention.Overrides(propertyBase.GetFieldInfoConfigurationSource()))
|| !ConfigurationSource.Convention.Overrides(propertyBase.GetFieldInfoConfigurationSource())
|| propertyBase.IsIndexerProperty())
{
return null;
}
Expand Down
7 changes: 7 additions & 0 deletions src/EFCore/Metadata/Internal/PropertyBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ public virtual void SetField([CanBeNull] FieldInfo fieldInfo, ConfigurationSourc
if (fieldInfo != null)
{
IsCompatible(fieldInfo, ClrType, DeclaringType.ClrType, Name, shouldThrow: true);

if (PropertyInfo != null
&& PropertyInfo.IsIndexerProperty())
{
throw new InvalidOperationException(
CoreStrings.BackingFieldOnIndexer(fieldInfo.GetSimpleMemberName(), DeclaringType.DisplayName(), Name));
}
}

if (PropertyInfo == null
Expand Down
8 changes: 8 additions & 0 deletions src/EFCore/Properties/CoreStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/EFCore/Properties/CoreStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1248,4 +1248,7 @@
<data name="NonIndexerEntityType" xml:space="preserve">
<value>Cannot add property '{property}' on entity type '{entity}' since there is no indexer on '{entity}' taking a single argument of type '{type}'.</value>
</data>
<data name="BackingFieldOnIndexer" xml:space="preserve">
<value>Cannot set backing field '{field}' for the indexer property '{entityType}.{property}'. Indexer properties are not allowed to use a backing field.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,29 @@ public void FieldInfo_set_by_annotation_is_used()
Assert.Equal("m_onTheRun", property.GetFieldName());
}

[ConditionalFact]
public void Backing_field_is_not_discovered_for_indexer_property()
{
var entityType = CreateModel().AddEntityType(typeof(IndexedClass));
var property = entityType.AddIndexedProperty("Nation", typeof(string));

RunConvention(property);
Validate(property);

Assert.Null(property.GetFieldName());
}

[ConditionalFact]
public void Setting_field_on_indexer_property_throws()
{
var entityType = CreateModel().AddEntityType(typeof(IndexedClass));
var property = entityType.AddIndexedProperty("Nation", typeof(string));

Assert.Equal(
CoreStrings.BackingFieldOnIndexer("nation", entityType.DisplayName(), "Nation"),
Assert.Throws<InvalidOperationException>(() => property.SetField("nation")).Message);
}

private void RunConvention(IMutableProperty property)
=> new BackingFieldConvention(CreateDependencies())
.ProcessPropertyAdded(
Expand Down Expand Up @@ -459,6 +482,17 @@ public object OnTheRun
}
}

private class IndexedClass
{
private string nation;
private string _nation;
private string _Nation;
private string m_nation;
private string m_Nation;

public object this[string name] => null;
}

#pragma warning disable RCS1222 // Merge preprocessor directives.
#pragma warning restore 649, 169
#pragma warning restore IDE0027 // Use expression body for accessors
Expand Down

0 comments on commit a8072e9

Please sign in to comment.