首页 > 解决方案 > 检查类是否实现了通用接口

问题描述

我正在使用以下通用函数来确定一个类是否实现了指定的接口:

private static bool HasFieldType<TEntity, TInterface>()
{
    return typeof(TInterface).IsAssignableFrom(typeof(TEntity));
}

这在大多数情况下都可以正常工作。

但是,我现在有一个具有通用参数的接口:

public interface IStatusField<TEnum> where TEnum : System.Enum
{
    TEnum Status { get; set; }
}

这会导致HasFieldType函数因unexpected use of unbound generic name错误而中断。

理想情况下,我想调用如下函数:

if (HasFieldType<TEntity, IStatusField<>>()) 
{
    // builder is an EntityTypeBuilder instance
    builder.Property("Status")
        .HasMaxLength(255)
        .HasConversion(new EnumToStringConverter<>());
}

但这不起作用,因为我没有为IStatusField<>或指定泛型类型EnumToStringConverter<>

有没有办法解决?

更新

此代码构成通用基IEntityTypeConfiguration类的一部分,如下所示:

public abstract class EntityTypeConfiguration<TPrimaryKey, TEntity> : IEntityTypeConfiguration<TEntity> where TEntity : Entity<TPrimaryKey>
{
    public void Configure(EntityTypeBuilder<TEntity> builder)
    {
        builder.HasKey(e => e.Id);

        builder.Property(e => e.Id)
            .IsRequired()
            .HasMaxLength(13)
            .HasValueGenerator<PrimaryKeyValueGenerator>();

        // Apply the generic interface properties
        builder.ApplyInterfaceFields<TPrimaryKey, TEntity>();

        // Apply any additional configuration
        this.OnConfigure(builder);
    }

    protected abstract void OnConfigure(EntityTypeBuilder<TEntity> builder);
}

// In an extension class, I have
public static void ApplyInterfaceFields<TPrimaryKey, TEntity>(this EntityTypeBuilder<TEntity> builder) where TEntity : Entity<TPrimaryKey>
{
    // Check other implementations (removed for brevity)

    // IStatusField implementation
    if (HasFieldType<TEntity, IStatusField<>())
    {
        builder.Property("Status")
            .HasMaxLength(255)
            .HasConversion(new EnumToStringConverter<>());
    }

}

在检查IStatusField实现时,我对指定的泛型类型一无所知。我认为这可能是更大的问题...

标签: c#genericsinterfaceentity-framework-core

解决方案


好的,所以我设法解决了这个问题。

它需要一些整理和一些错误检查,但以最原始的形式:

private static bool HasFieldType<TEntity>(Type interfaceType)
{
    var interfaces = typeof(TEntity).GetTypeInfo().ImplementedInterfaces;

    // Iterate through the interfaces
    foreach (var intf in interfaces)
    {
        // Compare interface names
        if (intf.FullName.Contains(interfaceType.FullName))
        {
            return intf.IsAssignableFrom(typeof(TEntity));
        }
    }

    return false;
}

现在使它能够工作:

// IStatusField implementation
if (HasFieldType<TEntity>(typeof(IStatusField<>)))
{
    builder.Property("Status")
        .HasMaxLength(255)
        .HasConversion<string>();
}

我可以使用 EF 的内置自动字符串到枚举的转换来完成繁重的工作。


推荐阅读