-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
While testing an experimental feature to add support for interface declarations, I found that types generated using the class keyword can't correctly override get/set methods associated with properties.
Steps to reproduce
Add-Type @'
namespace TypeTest {
public interface Interface {
string S { get; set; }
}
}
'@
# Execute this as a separate statement to ensure TypeTest.Interface is defined before the class definition is
class TestClass : TypeTest.Interface {
[string]$S
}
Expected behavior
New type [TestClass] implementing [TypeTest.Interface] should have been compiled and loaded.
Actual behavior
At line:1 char:1
+ class TestClass : TypeTest.Interface {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error during creation of type "TestClass". Error message:
Method 'get_S' in type 'TestClass' from assembly 'Powershell Class Assembly, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null' does not have an implementation.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : TypeCreationError
Solution
After comparing the CIL emitted by the C# compiler when implicitly implementing an interface property, I found that the get/set methods generated by the compiler are marked virtual.
The fix is to either attempt to discover properties with matching signatures in associated instances and mark the backing get/set methods virtual, or simply just mark all get/set methods virtual (might incur slight overhead in method resolution at runtime rather than at compile time)
Environment data
Name Value
---- -----
PSVersion 6.2.0-preview.1
PSEdition Core
GitCommitId 6.2.0-preview.1-79-g16569b157a430cc5d4a2e7bf189dcfef64beb31f
OS Microsoft Windows 10.0.17134
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0