C# 创建自己的自定义数据类型

C# 创建自己的自定义数据类型,c#,generics,types,C#,Generics,Types,如何在C#中创建自定义数据类型,然后将其用作泛型类型? 例如,我想创建一个1、3或6字节的数据类型 假设我们想要表示某种类型的记忆。存储器可以是各种类型,如RAM、EEPROM等。给定存储器包含的字大小可以是1字节、3字节或6字节。现在我们有: // Note: T could be UInt8, UInt24 or UInt48 class Memory<T> { // List of words filling up the memory public L

如何在C#中创建自定义数据类型,然后将其用作泛型类型?
例如,我想创建一个1、3或6字节的数据类型

假设我们想要表示某种类型的记忆。存储器可以是各种类型,如RAM、EEPROM等。给定存储器包含的字大小可以是1字节、3字节或6字节。现在我们有:

// Note: T could be UInt8, UInt24 or UInt48
class Memory<T>
{    
    // List of words filling up the memory
    public List<Word<T>> Words { get; set; }
    ...    
}

class Word<T>
{       

    // That might be a way to access the data?
    public byte[] Value { get; set; }
    // Should rather be:
    // public T Value { get; set; }

    public Word()
    {
        // Allocate bytes to "Value" based on word type
        List<byte> tmpList = new List<byte>();

        for(int i = 0; i < "sizeOf(T)";) 
            tmpList.Add(0);

        Value = tmpList.ToArray();
    }
}
//注意:T可以是UInt8、UInt24或UInt48
类内存
{    
//填满内存的单词列表
公共列表字{get;set;}
...    
}
类词
{       
//这可能是访问数据的一种方式?
公共字节[]值{get;set;}
//应该是:
//公共T值{get;set;}
公共词()
{
//根据字类型将字节分配给“值”
List tmpList=新列表();
对于(int i=0;i<“sizeOf(T)”;)
tmpList.Add(0);
Value=tmpList.ToArray();
}
}
我最初尝试使用枚举,但不是一种很好的方法:

public enum WordTypes: IConvertible
{
    /// <summary>One byte per word</summary>        
    [Description("One byte per word")]
    UInt8 = 8,
    /// <summary>Three bytes per word</summary>
    [Description("Three bytes per word")]
    UInt24 = 24,
    /// <summary>Six bytes per word</summary>
    [Description("Six bytes per word")]
    UInt48 = 48
}
公共枚举词类型:IConvertible
{
///每个字一个字节
[说明(“每个字一个字节”)]
UInt8=8,
///每个字三个字节
[说明(“每个字三个字节”)]
UInt24=24,
///每个字六个字节
[说明(“每个字六个字节”)]
UInt48=48
}
我还考虑过使用非托管内存,因为它是字节可访问的,并且可以更好地表示内存中的数据,但这可能有点过头了

编辑
@JeremyCaney提供了很棒的指针。

基于Jeremy的链接,您可以这样做:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;

namespace WordTypes
{
    [ComVisible(true)]
    [Serializable]
    [StructLayout(LayoutKind.Sequential)]

    public struct UInt24 : IComparable, IFormattable, IConvertible
    {
        internal uint m_value;

        public static explicit operator UInt24(uint v) => new UInt24(v);

        public const uint MaxValue = (uint)0xFFFFFF;
        public const short MinValue = unchecked((short)0x000000);

        public UInt24(uint v)
        {
            if (v > MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(v), $"Value too big - Max is {MaxValue}.");
            }
            if (v < MinValue)
            {
                throw new ArgumentOutOfRangeException(nameof(v), $"Value too small - Min is {MinValue}.");
            }

            this.m_value = v;
        }

        // Implement other required IComparable, IFormattable and IConvertible as needed here
        ....

    }
}
使用系统;
使用System.Runtime.InteropServices;
使用System.Diagnostics.Contracts;
命名空间字类型
{
[ComVisible(true)]
[可序列化]
[StructLayout(LayoutKind.Sequential)]
公共结构UInt24:IComparable、IFormattable、IConvertible
{
内部单位m_值;
公共静态显式运算符UInt24(uint v)=>新的UInt24(v);
公共const uint MaxValue=(uint)0xFFFFFF;
public const short MinValue=unchecked((short)0x000000);
公共UInt24(uint v)
{
如果(v>MaxValue)
{
抛出新ArgumentOutOfRangeException(nameof(v),$“值太大-最大值为{MaxValue}”);
}
如果(v
键位于显式运算符中,该运算符将用于与最小/最大定义值进行比较,如果不遵守边界,则抛出错误-注意,这是一个运行时错误
然后您可以这样使用它:

Word<UInt24> myWord = new Word<UInt24>();

myWord.Value = (UInt24)0x123456;   // This will work!
myWord.Value = (UInt24)0x1234567;  // This will fail as 0x1234567 > MaxValue!
wordmyword=新单词();
myWord.Value=(UInt24)0x123456;//这会有用的!
myWord.Value=(UInt24)0x1234567;//这将失败,因为0x1234567>MaxValue!

然后对其他需要的数据类型执行类似操作

任何类型都可以与genric一起使用。您能指定2字节4字节数据类型的含义吗?可能会使用短(2字节)/int(4字节),而任何类型都可以在泛型中使用,正如@Genfood的注释所示,听起来您可能需要研究创建,特别是结构。结构是轻量级的、不可变的类,许多内置CLR类型都是基于它的。@jason.kaisersmith:或者是一个家庭作业问题。它们通常看起来相同。您可能还希望交叉引用参考源代码,例如,或作为支持字节计数的基本结构的一个很好的示例。与基本类一样,基本结构可能非常简单。开箱即用结构要复杂得多,因为它们有许多比较器、转换器和解析器。你可能不需要这些。微软有一个很好的解决方案。