相关疑难解决方法(0)

使用泛型类型参数代替System.Type类型的参数.这是一种气味吗?

我经常看到(例如在许多模拟库中)方法,其中使用泛型类型参数来代替类型的参数System.Type.我特别谈到泛型类型仅在typeof(T)操作中使用的情况(即,在方法中的任何地方都没有使用类型T的实例,并且T不用于返回类型或其他参数).

例如,考虑以下方法:

public string GetTypeName(System.Type type) { return type.FullName; }
Run Code Online (Sandbox Code Playgroud)

这种方法通常伴随着通用版本:

public string GetTypeName<T>() { return GetTypeName(typeof(T)); }
Run Code Online (Sandbox Code Playgroud)

问题 是一种不好的做法还是一种好的做法?
这是一种语法糖还是还有更多呢?

我认为这是滥用语言功能来缩写对接受类型参数的方法的调用 System.Type

你觉得这有气味吗?这应该避免吗?或者这实际上是一种很好的做法(提供通用方法作为避免键入的快捷方式typeof()).

以下是使用我能想到的这种模式的一些实际问题:

  1. 如果添加了非System.Type类型的参数 - 可能需要将方法重写(如果参数的顺序在语义上很重要)到非泛型版本(否则一些参数将是泛型类型参数,而一些参数将是常规参数).
  2. 它需要两个方法(对于在编译时未知类型的情况,通用和非通用).因此增加了几乎毫无意义的单元测试.

另一方面,这是一种常见的做法(大多数总是正确的,对吧?)但更重要的是,当我对需要在编译时知道System.Type类型的单个参数的代码进行Extract Method重构时,ReSharper更喜欢该签名(和我学会了接受他们的建议,虽然不是出于信仰,但认真地).

c# coding-style

13
推荐指数
1
解决办法
651
查看次数

当作为具有接口约束的通用参数传递时,值类型是否装箱?

(作为回答这个问题的研究结果,我(我想我已经!)确定答案是"不".但是,我不得不在几个不同的地方看看这个,所以我觉得还有这个问题很有价值.但如果社区投票结束,我不会感到沮丧.)

例如:

void f<T>(T val) where T : IComparable
{
   val.CompareTo(null);
}

void g()
{
   f(4);
}
Run Code Online (Sandbox Code Playgroud)

4盒装?我知道明确地将值类型转换为它实现触发装箱的接口:

((IComparable)4).CompareTo(null); // The Int32 "4" is boxed
Run Code Online (Sandbox Code Playgroud)

我不知道的是,将值类型作为具有接口约束的泛型参数传递是否等于执行转换 - 语言"其中T是IC Comparable" 类似于建议转换,但只是转变TIComparable似乎它会打败通用的全部目的!

为了澄清,我想确保在上面的代码中没有发生这些事情:

  1. g调用时f(4),由于对参数类型有约束,因此4被强制转换IComparable为.IComparablef
  2. 假定(1)不发生,内f,val.CompareTo(null)不投valInt32IComparable为了调用CompareTo.

但我想了解一般情况; 不只是ints和IComparables 会发生什么.

现在,如果我将以下代码放入LinqPad:

void Main()
{
    ((IComparable)4).CompareTo(null);
    f(4);
}

void f<T>(T val) where T …
Run Code Online (Sandbox Code Playgroud)

c# generics clr boxing type-constraints

6
推荐指数
1
解决办法
1411
查看次数

标签 统计

c# ×2

boxing ×1

clr ×1

coding-style ×1

generics ×1

type-constraints ×1