为什么要使用具有类型约束的泛型方法而不是类型本身?


14

在另一个StackExchange问​​题中,我注意到有人在使用此原型:

void DoSomething<T>(T arg) where T: SomeSpecificReferenceType
{
    //Code....
}

请记住,只有一个类型约束(SomeSpecificReferenceType),这样写而不是简单地有什么区别和好处?

void DoSomething(SomeSpecificReferenceType arg)
{
    //Code....
}

在这两种情况下,arg都将进行编译时类型检查。在这两种情况下,方法的主体都可以安全地依赖arg编译时已知的特定类型的知识(或作为其后代)。

这是开发人员在学习普通继承之前热衷于泛型的一种情况吗?还是有一个合理的理由解释为什么这样写方法签名?


我几乎不了解C#,所以这只是一个猜测,但这不启用更有效的静态分发而不是动态分发吗?
安东·巴科夫斯基

Answers:


13

这是开发人员在学习普通继承之前热衷于泛型的一种情况吗?

是的,可能是。

还是有一个合理的理由解释为什么这样写方法签名?

也许吧。通常,如果有一个涉及的返回值T,或者使用了另一个参数,那就更有意义了T

但是,代码的内部可能使用T(也许作为序列化器的参数?)并且需要专门使用T而不是使用约束类。您偶尔会看到,当约束是与new约束配对的接口,并且方法的内胆T出于某种原因创建s时。

因此,虽然很少见到所需的约束版本,但有时还是需要它。它总是可能的方法用于需要它,但现在不和开发商留下它是不引入重大更改。


1

我想我记得自己在输入包含此内容的答案。

当时的原因是这样的:(
代码可能不同。只是为了说明在通用方法中对类型参数施加约束的可能原因之一。)

class SomeSingleton
{
    static Dictionary<Type, List<object>> staticTypeSpecificList;
    public void AddObjectToList<T>(T t) where T : SomeCommonThing
    {
        Type tt = t.GetType();
        List<object> list;
        if (!staticTypeSpecificList.TryGet(tt, out list))
        {
            list = new List<object>();
            staticTypeSpecificList.Add(tt, list);
        }
        list.Add(t);
    }
}

基本上,代码本身就是手动编码类型操作。它也可能与一些反射材料混在一起。

例如,通过使用Method<T>(T arg) where T : ...,可以将替换arg.GetType()typeof(T)。虽然,我不知道这种选择是好是坏。

我想这只是作者(可能是我或其他人)没有仔细考虑所有编码可能性的示例,而同时又过多地关注另一个问题/问题。


“可以用typeof(T)替换arg.GetType()”。当arg可以有效为null时(例如在某些序列化情况下),这很有用。
walpen'3
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.