C#C
C#2y ago
jborean

Create dynamic class that implements interface with static properties

Sorry for the PowerShell but I'm trying to figure out how to create a class that implements an interface with a static property and I have the following
using namespace System.Reflection
using namespace System.Reflection.Emit

$ErrorActionPreference = 'Stop'

Add-Type -TypeDefinition @'
public interface IProperty
{
    static abstract int Id { get; }
}

public class CSharpProperty : IProperty
{
    public static int Id { get => 1; }
}
'@

$ab = [AssemblyBuilder]::DefineDynamicAssembly(
    [AssemblyName]::new("MyAssembly"),
    [AssemblyBuilderAccess]::Run)
$mb = $ab.DefineDynamicModule("MyModule")
$tb = $mb.DefineType(
    "MyClass",
    [TypeAttributes]::Public,
    $null,
    [type[]]@([IProperty]))

$getAttr = $tb.DefineMethod(
    "get_Id",
    [MethodAttributes]"Public, Static, HideBySig, SpecialName",
    [int],
    [type]::EmptyTypes)
$getAttrIl = $getAttr.GetILGenerator()
$getAttrIl.Emit([OpCodes]::Ldc_I4_1)
$getAttrIL.Emit([OpCodes]::Ret)

$pb = $tb.DefineProperty(
    "Id",
    [PropertyAttributes]::None,
    [int],
    $null)
$pb.SetGetMethod($getAttr)

$null = $tb.CreateType()

[MyClass]::Id

It's failing with
Exception calling "CreateType" with "0" argument(s): "Virtual static method 'get_Id' is not implemented on type 'MyClass' from assembly 'MyAssembly, Version=0.0.0.0,Culture=neutral, PublicKeyToken=null'."
Looking at the IL code in sharplab.io for the equivalent C# code doesn't have anything jumping out at me https://sharplab.io/#v2:C4LglgNgPgAgzAAjAO2AUwE4DMCGBjNBASQAUMB7AB02AE8BYAKAG8mF2EYBGANgRwBGAZ2AZ8wJKmIATBMwQBzNMADcCAL5NNjJvE4AmBAGEAygAscGSmSo1aCEMRvUMdJq0YdOibnxQSiWXklCQBeAD4ELjVtdSA==. When adding the MethodAttributes.Virtual to the get_Id method builder it fails saying methods can't be static and virtual. Am I just missing something simple or is there something else I need to do here?
C#/VB/F# compiler playground.
Was this page helpful?