如何将类型传递给方法 - 键入参数vs泛型

Vil*_*lx- 16 c# generics parameters types factory

我有一个像工厂一样的对象方法.你给它一个类型,它创建一个实例并做一些其他的事情.一个优雅的方式(在我看来)是这样的:

public T MagicMethod<T>() where T: SomeBaseClass
{
    // Magic goes here
}
Run Code Online (Sandbox Code Playgroud)

但是这让FxCop感到不安,他说这是一个糟糕的风格 - 我得到一个"CA1004:通用方法应该提供类型参数"警告.关于不使用推理和东西的事情.所以,我能想到的另一种方式是这样的:

public SomeBaseClass MagicMethod(Type T)
{
    // Same magic goes here
}
Run Code Online (Sandbox Code Playgroud)

我认为这不如许多帐户的第一种方法,但风格规则......关于警告的MSDN文章甚至说没有理由压制它.

我是否通过抑制此警告来做到这一点?

Ada*_*son 17

我相信你误解了FxCop告诉你什么,可能是因为它的措辞不太理想.这意味着泛型方法应该提供该类型的参数,不是泛型方法应该具有提供运行时Type实例的非泛型重载.例如,

public void DoSomething<T>(T myParam);
Run Code Online (Sandbox Code Playgroud)

myParam是它所指的那种参数.正如你所说,它想要这个的原因是推断.这允许你做一些像......

string foo = "bar";

DoSomething(foo);
Run Code Online (Sandbox Code Playgroud)

而不是必须写

DoSomething<string>(foo);
Run Code Online (Sandbox Code Playgroud)

在您的情况下,可以禁止警告,因为您希望用户明确指定类型.不过,我建议您(假设您的构造函数是无参数的)将您更改wherewhere T : SomeBaseClass, new().这意味着它将指示编译器要求传入的任何类型都具有无参数构造函数.这也意味着您可以new T()在代码中执行此操作.


Shu*_*oUk 5

压制这个警告我没有问题.对于初学者来说,MS自己的代码中的等价物是Activator.CreateInstance<T>()

public static T CreateInstance<T>()
Run Code Online (Sandbox Code Playgroud)

这意味着分析规则应该考虑泛型参数是否涵盖方法的返回类型 ...

以前在很多地方都提到过:

例如,规则中存在先前的错误:

public static void GenericMethod<T>(List<T> arg);
Run Code Online (Sandbox Code Playgroud)

以前会触发它(在2005 SP1中修复).

我建议为您的具体示例提交连接错误


kyo*_*ryu 2

FXCop 警告只是警告。就像隐式强制转换警告一样,它们可以让您知道您正在做的事情可能会出现您没有预料到的行为,或者可能不是您想要的。

通过查看代码来处理隐式强制转换警告,确定您是否确实打算这样做,如果是,则添加显式强制转换。

FXCop 也是如此。查看警告,查看代码,并确定警告是否有效。如果是,请修复它。如果没有,就压制它。抑制相当于明确的强制转换 - “是的,FXCop,我确定我想这样做。”

如果这确实是一个错误,那么它可能是一个编译器错误。

  • 是的,但是包含此警告详细信息的 MSDN 页面明确指出“您不应抑制此警告”。老实说,我比 FXCop 团队的集体智慧更聪明吗? (8认同)