gpt4 book ai didi

c# - 如何将泛型类限制为某些类型(包括 native 数据类型)

转载 作者:行者123 更新时间:2023-11-30 17:47:36 26 4
gpt4 key购买 nike

我想创建一个通用结构(基本上是一个数组)并将可能的类型限制为 ISerializable 类型和一堆 native 数据类型,如 int、uint、float、double、char 等。问题是我无法标记这些具有接口(interface)的 native 数据类型,我的研究表明,不可能在泛型类型约束构造(where 子句)中使用诸如 关键字之类的东西。所以问题是我怎样才能意识到这一点?

如果您对上下文感兴趣:我有一个 BinaryStream 类负责从/向流读取和写入。 自定义 ISerializable 接口(interface)具有函数void Serialize(BinaryStream f),可以从/向流f 读取或写入(取决于f 中的状态)。实际写入或读取的当然是构成结构的 native 数据类型。这些通过 f.Transfer(ref data) 读取或写入。使用 .NET 框架中的标准 BinarySerializer 不是一种选择,因为它必须以自定义方式完成。

public class AutoArray<T> : ISerializable where T : ISerializable //or int or uint or float etc.
{
private uint n;
private T[] data;

public void Serialize(BinaryStream f)
{
f.Transfer(ref n);
for (int i = 0; i < n; i++)
if (data[i] is ISerializable) data[i].Serialize(f);
else f.Transfer(ref data[i]);
}
}

最佳答案

您的研究为您提供了正确的信息 - .NET 不允许您将泛型限制为某些抽象数字数据类型,因为它们(数字数据类型)没有任何通用接口(interface)。这是一种耻辱,有时甚至是一个问题,但这仍然是事实。

如果您确实拥有可以处理数字类型的非常通用的代码,那么您可以尝试在 C++\CLI 中实现您的类 - 它是 C++,因此它允许您使用模板,并且它是支持泛型的 .NET 语言:

// C# - use base interface for your serializer, define it in separate assembly(or directly in C++\CLI)
public interface IMySerializer<T> {...}

// C++\CLI - add the reference to the project with IMySerializer<T>
template<class Type>
public ref abstract class MyNumericSerializerBase : IMySerializer<Type> {...};

// C++\CLI - you can't use template class in C# - it must be specialized
public ref class MyIntSerializer : MyNumericSerializerBase<Int32> {...};

然后将创建的 C++\CLI dll 添加为对项目的引用。好吧,您仍然需要创建这样的 MyIntSerializer对于每种数字类型,但至少您不必复制所有代码。并有效地获得所需的IMySerializer<T>您可以使用一些工厂来搜索特定的 IMySerializer<T>通过属性反射或通过 IsAssignableFrom :

// C#
public class MySerializerFactory
{
public IMySerializer<T> GetSerializer<T>() {...}
}

这不是最简单的解决方案,但当我需要创建在计算中仅数字类型不同的类型时,我会使用它。

编辑:

使用 C++\CLI 会不会有点矫枉过正?好吧,对于简单的情况,应用起来并不难,但是如果你不会使用类似的东西

template<class Type>
public ref abstract class MyNumericSerializerBase : IMySerializer<Type>
{
public:
Type GetValue(Type first, Type second)
{
return first + (second / 2); // The REAL advantage(and potential problems source) of C++\CLI templates
}
}

那么除了避免代码重复之外,这种方法并没有真正的优势。并且,考虑到您可以在 C# 中实现特定序列化程序的数字类型很少:

// C#
public class MyInt32Serializer: IMySerializer<Int32> {...}

并使用相同的工厂(或定位器)模式:

// C#
public class MySerializerFactory
{
public IMySerializer<T> GetSerializer<T>() {...}
}

可以像描述的那样找到具体的实现者here

关于c# - 如何将泛型类限制为某些类型(包括 native 数据类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24478508/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com