You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否创建Object<T>类集合?未指定T时如何存储CommonProperty<T>?

嘿,这两个问题都是泛型使用中很常见的场景,我来给你一步步拆解清楚:

关于自定义泛型Object类的可行性

当然可以创建一组泛型的Object<T>类,但有个小提醒:C#里已经有系统自带的System.Object类型,为了避免命名冲突,建议你换个更清晰的名字,比如GenericObject<T>。

举个简单的自定义泛型类示例:

public class GenericObject<T>
{
    public T Content { get; set; }
    // 你可以根据需求添加更多属性、方法
}

使用的时候,你可以轻松实例化不同类型的对象:

var intObj = new GenericObject<int> { Content = 42 };
var stringObj = new GenericObject<string> { Content = "Hello World" };
var dateObj = new GenericObject<DateTime> { Content = DateTime.Now };

完全没问题,泛型类的核心就是为不同类型提供统一的模板,所以这种用法是完全合法且常用的。

如何存储不同T类型的CommonProperty实例

你想要的List<CommonProperty<T>>直接定义是不行的——因为T是开放构造类型,集合需要的是封闭构造类型(比如明确指定T=int或T=string),但这样的集合只能存储同一种T的实例,没法混合不同类型的CommonProperty。

要实现存储任意T的CommonProperty<T>实例,最推荐的方案是定义一个非泛型的基类或接口,让CommonProperty<T>继承/实现它,然后用基类/接口类型的集合来存储。

具体实现步骤:

1. 定义非泛型接口

先创建一个包含所有非泛型公共成员的接口(比如ICommonProperty),把Name、Type这些和T无关的属性放进去,再添加泛型成员的非泛型访问方法:

// 假设PropType是你定义的枚举类型
public enum PropType { Int, String, DateTime /* 其他类型 */ }

public interface ICommonProperty
{
    string Name { get; set; }
    PropType Type { get; set; }
    object GetValue();
    void SetValue(object value);
    IEnumerable<object> GetPossibleValues();
}

2. 修改CommonProperty实现接口

让你的泛型类实现这个接口,同时保留原有的泛型成员:

internal class CommonProperty<T> : ICommonProperty
{
    public string Name { get; set; }
    public PropType Type { get; set; }
    public List<T> PossibleValues { get; set; }
    
    private T _value;
    public T Value 
    { 
        get { return _value; } 
        set 
        {
            // 这里建议用EqualityComparer<T>,避免引用类型为null时的空引用异常
            if (!EqualityComparer<T>.Default.Equals(_value, value)) 
            { 
                _value = value; 
            } 
        } 
    }

    // 实现接口的非泛型方法
    public object GetValue() => Value;
    
    public void SetValue(object value)
    {
        if (value is T typedValue)
        {
            Value = typedValue;
        }
        else
        {
            throw new ArgumentException($"值必须是{typeof(T).Name}类型", nameof(value));
        }
    }

    public IEnumerable<object> GetPossibleValues() 
        => PossibleValues?.Cast<object>() ?? Enumerable.Empty<object>();
}

3. 使用接口类型的集合存储

现在你就可以创建List<ICommonProperty>来存储任意T的CommonProperty<T>实例了:

var propertyList = new List<ICommonProperty>();

// 添加不同类型的CommonProperty实例
propertyList.Add(new CommonProperty<int> 
{ 
    Name = "年龄", 
    Type = PropType.Int, 
    Value = 30, 
    PossibleValues = new List<int> { 18, 25, 30, 35 } 
});

propertyList.Add(new CommonProperty<string> 
{ 
    Name = "姓名", 
    Type = PropType.String, 
    Value = "Chris", 
    PossibleValues = new List<string> { "Alice", "Bob", "Chris" } 
});

// 遍历集合访问成员
foreach (var prop in propertyList)
{
    Console.WriteLine($"属性名: {prop.Name}, 类型: {prop.Type}, 当前值: {prop.GetValue()}");
}

其他不推荐的方案

  • 使用ArrayList:这是.NET Framework早期的非泛型集合,会导致装箱拆箱,失去类型安全,容易引发运行时错误。
  • 使用List<dynamic>:虽然可以存储任意类型,但编译时不会做类型检查,同样存在运行时风险,除非特殊场景不建议使用。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:16:49