C#中是否存在Swift带关联属性枚举的等价实现方案?
在C#中实现Swift带关联值枚举的方案
Swift的带关联值枚举是一种类型安全的变体处理方式,在C#中可以通过以下几种方案实现类似效果,避免你原方案中强制类型转换的繁琐与不安全:
1. 类层次结构+模式匹配
通过抽象基类定义统一类型,每个枚举分支对应一个子类,配合C#模式匹配实现类型安全的分支处理:
// 抽象基类,定义统一的InputType类型 public abstract class InputType { } // 对应Swift中的.unknown case public class UnknownInput : InputType { } // 对应.data(Data) case public class DataInput : InputType { public byte[] Data { get; } public DataInput(byte[] data) => Data = data; } // 对应.profile(id: String, name: String, dateOfBirth: Date) case,用记录类型简化定义 public record ProfileInput(string Id, string Name, DateTime DateOfBirth) : InputType; // 对应.photos([Image]) case public class PhotosInput : InputType { public List<Image> Photos { get; } public PhotosInput(List<Image> photos) => Photos = photos; } // 使用示例,完全类型安全,无需强制转换 public void Setup(InputType inputType) { switch (inputType) { case DataInput dataInput: DataSetup(dataInput.Data); break; case ProfileInput profileInput: ProfileSetup(profileInput.Id, profileInput.Name, profileInput.DateOfBirth); break; case PhotosInput photosInput: ImagesSetup(photosInput.Photos); break; case UnknownInput: throw new UnknownDataTypeException(); default: throw new NotSupportedException("不支持的输入类型"); } } // 辅助方法示例 private void DataSetup(byte[] data) { } private void ProfileSetup(string id, string name, DateTime dob) { } private void ImagesSetup(List<Image> photos) { } public class Image { } public class UnknownDataTypeException : Exception { }
2. .NET 7+ 辨别联合(Discriminated Unions)
从C# 11(.NET 7)开始,官方支持辨别联合,语法更接近Swift枚举,用record可快速定义:
// 定义辨别联合,每个分支对应一个密封的record public abstract record InputType { public sealed record Unknown() : InputType; public sealed record Data(byte[] Value) : InputType; public sealed record Profile(string Id, string Name, DateTime DateOfBirth) : InputType; public sealed record Photos(List<Image> Value) : InputType; } // 使用示例,支持直接解构匹配 public void Setup(InputType inputType) { switch (inputType) { case InputType.Data(byte[] data): DataSetup(data); break; case InputType.Profile(string id, string name, DateTime dob): ProfileSetup(id, name, dob); break; case InputType.Photos(List<Image> photos): ImagesSetup(photos); break; case InputType.Unknown: throw new UnknownDataTypeException(); default: throw new NotSupportedException(); } }
这种方式完全类型安全,代码结构紧凑,和Swift枚举的使用体验最接近。
3. 值类型版辨别联合(结构体)
如果需要值类型特性(如栈分配、无引用开销),可以用record struct实现:
public abstract record struct InputType { public sealed record struct Unknown() : InputType; public sealed record struct Data(byte[] Value) : InputType; public sealed record struct Profile(string Id, string Name, DateTime DateOfBirth) : InputType; public sealed record struct Photos(List<Image> Value) : InputType; } // 使用方式和类版本一致,无需修改调用逻辑
对比原方案的优势
以上方案均为编译期类型安全,无需将值存为Object再强制转换,避免了运行时类型转换错误,同时分支处理代码可读性更高,与Swift枚举的使用逻辑对齐。
内容的提问来源于stack exchange,提问作者Bawenang Rukmoko Pardian Putra
相关产品推荐
相关产品推荐

