You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何实现无需强制转换的C#不同泛型类型集合?

基于泛型派生类的类型区分方案实现

你好!看你给出的代码框架,应该是想要通过基类的DerivedType字段来区分不同的泛型派生类,并且每个派生类有自己的泛型属性。我先帮你补全未完成的OtherDerivedClass<T>代码,然后针对这类场景的常见需求给出实用的实现方案。

补全后的完整代码

先把你未写完的逻辑补全,让代码闭环:

public class BaseClass 
{ 
    public int DerivedType { get; set; } 
}

public class DerivedClass<T> : BaseClass 
{ 
    public DerivedClass(T initialValue) 
    { 
        DerivedType = 1; 
        Property = initialValue; 
    } 
    public T Property { get; set; } 
}

public class OtherDerivedClass<T> : BaseClass 
{ 
    public OtherDerivedClass(T initialValue) 
    { 
        DerivedType = 2; 
        OtherProperty = initialValue; 
    } 
    public T OtherProperty { get; set; } 
}

常见场景解决方案

1. 从BaseClass实例安全访问派生类的泛型属性

如果你手里只有BaseClass的实例,想要根据DerivedType的值安全访问对应派生类的泛型属性,推荐用C# 7.0+的类型模式匹配,既安全又简洁:

public void HandleDerivedInstance(BaseClass instance)
{
    switch (instance)
    {
        case DerivedClass<string> derivedString:
            Console.WriteLine($"字符串类型DerivedClass的属性值: {derivedString.Property}");
            break;
        case DerivedClass<int> derivedInt:
            Console.WriteLine($"整数类型DerivedClass的属性值: {derivedInt.Property}");
            break;
        case OtherDerivedClass<DateTime> otherDerivedDate:
            Console.WriteLine($"日期类型OtherDerivedClass的属性值: {otherDerivedDate.OtherProperty}");
            break;
        default:
            // 不确定泛型类型时,用反射兜底访问属性
            var propertyName = instance.DerivedType == 1 ? "Property" : "OtherProperty";
            var propertyValue = instance.GetType().GetProperty(propertyName)?.GetValue(instance);
            Console.WriteLine($"未知泛型类型的属性值: {propertyValue}");
            break;
    }
}

2. 动态创建对应类型的派生类实例

如果需要根据DerivedType和初始值动态创建泛型派生类实例,可以写一个泛型工厂方法:

public BaseClass CreateDerivedInstance<T>(int derivedType, T initialValue)
{
    return derivedType switch
    {
        1 => new DerivedClass<T>(initialValue),
        2 => new OtherDerivedClass<T>(initialValue),
        _ => throw new ArgumentOutOfRangeException(nameof(derivedType), "不支持的派生类类型标识")
    };
}

调用示例:

// 创建字符串类型的DerivedClass
var stringDerived = CreateDerivedInstance<string>(1, "Hello World");
// 创建整数类型的OtherDerivedClass
var intOtherDerived = CreateDerivedInstance<int>(2, 999);

3. 优化建议:用枚举替代硬编码数字

目前用12标识派生类类型,可读性差且容易出错,建议定义枚举替代:

public enum DerivedTypeEnum
{
    DerivedClass = 1,
    OtherDerivedClass = 2
}

// 修改BaseClass的属性类型
public class BaseClass 
{ 
    public DerivedTypeEnum DerivedType { get; set; } 
}

// 派生类构造函数同步修改赋值
// DerivedType = DerivedTypeEnum.DerivedClass;
// DerivedType = DerivedTypeEnum.OtherDerivedClass;

这样后续维护代码时,不用再记数字对应的类型,可读性和可维护性会提升很多。


内容的提问来源于stack exchange,提问作者Kaloyan Manev

火山引擎 最新活动