为什么 C# 不支持泛型的泛型(具有参数化类型的泛型)?

发布于 2024-12-08 18:36:01 字数 1391 浏览 0 评论 0原文

最近(可能是设计缺陷),当需要拥有 MyType 集合(其中 T 不固定)时,我面临一项常规任务(即整个一个中的多个不同泛型实例化)收藏)。

由于它被广泛提议(对于这种情况),声明了一个抽象类:

public abstract class MyType {}
public class MyType<T>: MyType {}

然后我有一个 MyType 的集合。 然而,对于这个集合,我有一个限制,即任何类型 T 的元素都不能超过一个。

因此,我对 ICollection 进行了一些自定义实现。 我想包含一个方法 Get() 来获取与类型 TParam 相对应的项目。稍后使用如下:

MyCollection<MyType> collection = new MyCollection<MyType>();
MyType<int> myInt = collection.Get<int>();

然而,我意外地发现我什至无法声明它:

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } //this won't compile

因为内部泛型(或所谓的“泛型的泛型”)既不受 C# 支持,也不被 .NET 支持(我想)。您认为这些限制背后是否有任何具体原因(复杂性除外)?

更新1.询问编译器版本和编译器错误。

微软 C#、.NET 3.5 (Visual Studio 2010)。 错误:

错误CS0081:类型参数声明必须是标识符而不是 类型

错误 CS0246:类型或命名空间名称“TCustom”无法 找到(您是否缺少 using 指令或程序集引用?)

更新 2。询问我是否需要修复或解释原因。我真的很想知道为什么。但如果你对问题有好的解决方案,也欢迎。

更新3。这个问题可能已经在此博文。看来 CLR 团队承受着巨大的压力,要求不要使语言过于复杂。

Recently (perhaps of design shortcomings) I faced a regular task when required to have a collection of MyType<T> where T is not fixed (i.e. multiple various generics instantiations throughout one collection).

As it's widely proposed (for such cases) an abstract class was declared:

public abstract class MyType {}
public class MyType<T>: MyType {}

and then I'm having a collection of MyType.
However for this collection I had a constraint of having no more than one element for any type T.

Hence, I made a bit of custom implementation of ICollection<TBase>.
I wanted to include there a method Get<TParam>() for getting an item corresponding to type TParam. To be later used like:

MyCollection<MyType> collection = new MyCollection<MyType>();
MyType<int> myInt = collection.Get<int>();

However I unexpectedly discovered that I can't even declare it:

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } //this won't compile

because inner generics (or so-called "generics of generics") are neither supported by C# nor by .NET (I suppose). How do you think, were there any specific reasons behind such limitations (except for complexity)?

UPDATE 1. Asked for compiler version and compiler errors.

Microsoft C#, .NET 3.5 (Visual Studio 2010).
Errors:

error CS0081: Type parameter declaration must be an identifier not a
type

error CS0246: The type or namespace name 'TCustom' could not be
found (are you missing a using directive or an assembly reference?)

UPDATE 2. Asked whether I need a fix or explanations why. I really wanna know WHY. But if you have good solutions to the problem, you are also welcome.

UPDATE 3. The question might be answered already in this blog post. It appears that CLR team was under big pressure not to overcomplicate the language.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

在你怀里撒娇 2024-12-15 18:36:01

在这种情况下,您可以简单地将数据隐藏在非通用字典中:

private Dictionary<Type, object> _Data;

然后使用 Get 方法:

public MyType<TParam> Get<TParam>()
{ 
    return (MyType<TParam>)_Data[typeof(TParam)];
}

如果 TParam 类型不相关,则没有通用数据无论如何,结构都会给你类型安全,那为什么还要尝试呢?

In this case you could simply hide the data in a non-generic dictionary:

private Dictionary<Type, object> _Data;

and then your Get method:

public MyType<TParam> Get<TParam>()
{ 
    return (MyType<TParam>)_Data[typeof(TParam)];
}

If the TParam types aren't related, there is no common data structure that will give you type-safety anyway, so why even try?

浮生未歇 2024-12-15 18:36:01

为什么你需要

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } 

当通用类型(在你的情况下为 MyType)已知时,你不能做

public MyType<TParam> Get<TParam>() { 
  return (MyType<TParam>)_items.FirstOrDefault(i => i is MyType<TParam>);
}

或者我错过了什么?

Why exactly do you need

public TCustom<TParam> Get<TParam, TCustom<TParam>>() { } 

When the generic type (MyType in your case) is known, can't you just do

public MyType<TParam> Get<TParam>() { 
  return (MyType<TParam>)_items.FirstOrDefault(i => i is MyType<TParam>);
}

Or am I missing something?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文