能否创建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
相关产品推荐
相关产品推荐

