Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/System.Management.Automation/engine/parser/PSType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,19 @@ private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, ou
return baseClass ?? typeof(object);
}

private bool ShouldImplementProperty(string name, Type type)
{
foreach (var interfaceType in _typeBuilder.GetInterfaces())
{
if (interfaceType.GetProperty(name, type) != null)
{
return true;
}
}

return false;
}

public void DefineMembers()
{
// If user didn't provide any instance ctors or static ctor we will generate default ctor or static ctor respectively.
Expand Down Expand Up @@ -576,6 +589,11 @@ private PropertyBuilder EmitPropertyIl(PropertyMemberAst propertyMemberAst, Type
// The property set and property get methods require a special set of attributes.
var getSetAttributes = Reflection.MethodAttributes.SpecialName | Reflection.MethodAttributes.HideBySig;
getSetAttributes |= propertyMemberAst.IsPublic ? Reflection.MethodAttributes.Public : Reflection.MethodAttributes.Private;
if (ShouldImplementProperty(propertyMemberAst.Name, type))
{
getSetAttributes |= Reflection.MethodAttributes.Virtual;
}

if (propertyMemberAst.IsStatic)
{
backingFieldAttributes |= FieldAttributes.Static;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ Describe 'Classes inheritance syntax' -Tags "CI" {
[MyComparable].GetInterface("System.IComparable") | Should -Not -BeNullOrEmpty
}

It 'can implement .NET interface properties' {
Add-Type -TypeDefinition 'public interface InterfaceWithProperty { int Integer { get; set; } }'
$C1 = Invoke-Expression 'class ClassWithInterfaceProperty : InterfaceWithProperty { [int]$Integer } [ClassWithInterfaceProperty]::new()'
$getter = $C1.GetType().GetMember('get_Integer')
$getter.ReturnType.FullName | Should -Be System.Int32
$getter.Attributes -band [System.Reflection.MethodAttributes]::Virtual |Should -Be ([System.Reflection.MethodAttributes]::Virtual)
}

It 'allows use of defined later type as a property type' {
class A { static [B]$b }
class B : A {}
Expand Down