将方法类型参数限制为 class 泛型类型的基础
Constrain method type argument to be base of class generic type
我想确保方法类型参数是 class 泛型类型的基类型,所以首先我自然地写了这个:
public class FivePM<T> {
public void drink<M>(M x) where T : M {}
}
有什么具体原因导致这不起作用吗?
背景
我写了容器 class Bag<B>
来存储不同实例之间共享的项目,所以如果将项目添加到另一个包中,它会自动从一个包中删除。这是由 BagSet<BT>
内部完成的,它存放普通物品的袋子。我希望 bag 通用类型成为集合中项目的最低常见类型,但不希望 constrian B
完全是 BT
但对于任何派生类型。
我已经设法使袋子的类型安全 public 接口满足我的要求,但由于通用约束限制,袋子构造看起来很笨拙,我不能使用列表初始化程序:
BagSet<object> bset = new BagSet<object>();
Bag<int> suitcase = bset.newBag<int>();
public class BagSet<T> : BagSetBase {
public Bag<B> newBag<B>(string name = null, params B[] items) where B : T {
var b = new Bag<B>(this, name);
for (int i = 0; i < items.Length; i++) b.Add(items[i]);
return b;
}
}
总有一天会改进通用约束吗?也许我应该等一下再广泛地做这样的事情。
使用您的真实代码,如果您让 class Bag
采用两种类型并处理继承要求会怎么样 - 毕竟,您不关心 BagSet
:
public class BagSet<T> {
public Bag<B, T> newBag<B>(string name = null, params B[] items) where B : T {
var b = new Bag<B, T>(this, name);
for (int i = 0; i < items.Length; i++) b.Add(items[i]);
return b;
}
}
public class Bag<B, T> where B : T {
BagSet<T> common;
string bsname;
public Bag(BagSet<T> bs, string name) {
common = bs;
bsname = name;
}
public void Add(B item) {
}
}
然后你可以像这样声明它们:
var bset = new BagSet<object>();
var suitcase = bset.newBag<int>();
我想你也许可以让这个工作:
public class FivePM<T, M> where T : M
{
public void drink(M x)
}
但是你的问题又让我困惑了,现在已经过了午夜,所以我可能错了,我可能误解了这个问题....或者也许不是?
Is there any specific reason why this can't work?
如果您的意思是有 合乎逻辑的 理由说明这种限制没有意义,那么没有。这是一个非常明智的约束,并且有支持这种约束的语言。 Java,例如。还有 Scala。
如果您的意思是这在 C# 中不起作用是有原因的,那很简单。 从来没有人在 C# 中实现过该功能。 为了使某个功能在 C# 中工作,必须有人想到它、设计它、编写规范、实施规范、编写测试,然后将其运送给客户。在那些必要的步骤中,只有第一步发生了。
Are generic constrains going to be improved someday?
要求预测未来的问题在 Stack Overflow 上属于题外话。我们没有能力可靠地预测未来。
如果您希望此功能出现在 C# 的未来版本中,请考虑在 github 论坛上提倡它。
我想确保方法类型参数是 class 泛型类型的基类型,所以首先我自然地写了这个:
public class FivePM<T> {
public void drink<M>(M x) where T : M {}
}
有什么具体原因导致这不起作用吗?
背景
我写了容器 class Bag<B>
来存储不同实例之间共享的项目,所以如果将项目添加到另一个包中,它会自动从一个包中删除。这是由 BagSet<BT>
内部完成的,它存放普通物品的袋子。我希望 bag 通用类型成为集合中项目的最低常见类型,但不希望 constrian B
完全是 BT
但对于任何派生类型。
我已经设法使袋子的类型安全 public 接口满足我的要求,但由于通用约束限制,袋子构造看起来很笨拙,我不能使用列表初始化程序:
BagSet<object> bset = new BagSet<object>();
Bag<int> suitcase = bset.newBag<int>();
public class BagSet<T> : BagSetBase {
public Bag<B> newBag<B>(string name = null, params B[] items) where B : T {
var b = new Bag<B>(this, name);
for (int i = 0; i < items.Length; i++) b.Add(items[i]);
return b;
}
}
总有一天会改进通用约束吗?也许我应该等一下再广泛地做这样的事情。
使用您的真实代码,如果您让 class Bag
采用两种类型并处理继承要求会怎么样 - 毕竟,您不关心 BagSet
:
public class BagSet<T> {
public Bag<B, T> newBag<B>(string name = null, params B[] items) where B : T {
var b = new Bag<B, T>(this, name);
for (int i = 0; i < items.Length; i++) b.Add(items[i]);
return b;
}
}
public class Bag<B, T> where B : T {
BagSet<T> common;
string bsname;
public Bag(BagSet<T> bs, string name) {
common = bs;
bsname = name;
}
public void Add(B item) {
}
}
然后你可以像这样声明它们:
var bset = new BagSet<object>();
var suitcase = bset.newBag<int>();
我想你也许可以让这个工作:
public class FivePM<T, M> where T : M
{
public void drink(M x)
}
但是你的问题又让我困惑了,现在已经过了午夜,所以我可能错了,我可能误解了这个问题....或者也许不是?
Is there any specific reason why this can't work?
如果您的意思是有 合乎逻辑的 理由说明这种限制没有意义,那么没有。这是一个非常明智的约束,并且有支持这种约束的语言。 Java,例如。还有 Scala。
如果您的意思是这在 C# 中不起作用是有原因的,那很简单。 从来没有人在 C# 中实现过该功能。 为了使某个功能在 C# 中工作,必须有人想到它、设计它、编写规范、实施规范、编写测试,然后将其运送给客户。在那些必要的步骤中,只有第一步发生了。
Are generic constrains going to be improved someday?
要求预测未来的问题在 Stack Overflow 上属于题外话。我们没有能力可靠地预测未来。
如果您希望此功能出现在 C# 的未来版本中,请考虑在 github 论坛上提倡它。