C# 如何将类型传递给方法类型参数与泛型

C# 如何将类型传递给方法类型参数与泛型,c#,generics,parameters,types,factory,C#,Generics,Parameters,Types,Factory,我有一个对象的方法,有点像工厂。你给它一个类型,它创建一个实例并做一些其他的事情。在我看来,一种优雅的方式是: public T MagicMethod<T>() where T: SomeBaseClass { // Magic goes here } public SomeBaseClass MagicMethod(Type T) { // Same magic goes here } 我相信这在很多方面不如第一种方法,但风格规则。。。MSDN关于警告的文章甚

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

public T MagicMethod<T>() where T: SomeBaseClass
{
    // Magic goes here
}
public SomeBaseClass MagicMethod(Type T)
{
    // Same magic goes here
}
我相信这在很多方面不如第一种方法,但风格规则。。。MSDN关于警告的文章甚至说没有理由压制它


我到底是不是压制了这个警告?第二种方法甚至不等同于第一种方法。在第二种情况下,您实际上得到了一个类型,但无法实例化该类型的对象(除非使用反射--eeek!),并且必须显式声明返回类型(这与泛型的初衷背道而驰)

请参见关于抑制它的注释。看来可以压制了

编辑:现在这里是另一个想法。如果您将其更改为“out”参数,并且没有通过return变量返回它,该怎么办?那么它会删除警告吗

public void MagicMethod<T>( out T retVar ) where T: SomeBaseClass
{
    // Magic goes here
}
public void MagicMethod(out T retVar),其中T:SomeBaseClass
{
//这里有魔法
}

就我个人而言,我会为Fxcop中的大多数警告而烦恼

你似乎知道自己在做什么,为什么一些自动化的软件会知道得更好


嗯,这是个猜测。

我相信你误解了FxCop告诉你的内容,可能是因为它的措辞不够理想。这意味着泛型方法应该提供一个属于该类型的参数,而不是泛型方法应该具有一个非泛型重载,该重载提供一个运行时
类型
实例。比如说,

public void DoSomething<T>(T myParam);
而不是必须写作

DoSomething<string>(foo);
DoSomething(foo);

在您的情况下,可以取消显示警告,因为您希望用户显式指定类型。但是,我建议(假设构造函数是无参数的)将
where
更改为
where T:SomeBaseClass,new()
。这意味着它将指示编译器要求传入的任何类型都具有无参数构造函数。这也意味着您可以在代码中执行
new T()

我对取消此警告没有问题。对于初学者来说,微软自己的代码中的等价物是

publicstatict CreateInstance()

这意味着分析规则应该考虑方法的返回类型是否被泛型参数…< /P>覆盖。 这一点以前在很多地方都提到过:

规则中也有以前的错误,例如:

public static void GenericMethod<T>(List<T> arg);
publicstaticvoid-GenericMethod(List-arg);
以前会触发它()


我建议为您的特定示例提交一个连接错误

FXCop警告只是警告。就像隐含的演员警告一样,它们可以让你知道你正在做的事情可能有你没有预料到的行为,或者可能不是你想要的

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

FXCop也是这样。查看警告,查看代码,并确定警告是否有效。如果是,请修复它。如果没有,请将其抑制。抑制相当于显式强制转换——“是的,FXCop,我肯定我想这样做。”


如果它真的是一个错误,那么它可能是一个编译器错误。

首先,警告只是为了确保调用方在知情的情况下执行所有操作。可以在不传递任何类型参数的情况下调用方法,因为编译器事先知道对象的类型。FxCop告诉您让它成为隐式的,这样使用泛型和非泛型重载的语法看起来是相同的(我不同意这一原则,但这是个人的,在这里不相关)


其次,你的第二种方法会造成比你现在想象的更大的伤害。这里没有编译时类型检查,因此如果您使用它,会收到运行时无效强制转换异常的警告。

FxCop将触发该警告,即使您在一个或多个参数中使用了泛型类型参数,如果它没有“剥离”:

public void LinkedList片段(LinkedList集合,谓词匹配)
{
...
}
前几天,至少有规则“CA1004”在具有此签名的方法上“出错”触发


为了比FxCop团队更聪明,我不确定规则是否能够在所有情况下正确确定代码,这就是信心水平的目的:)

完全误解了你的问题,因此我删除了我的答案。没关系,因为我从未看到过你的答案。:)可能吧,但使用起来不太舒服。:)没错,在这一点上不能怪你。嗯,我认为比我更有才华和经验的开发人员编写了这个工具,如果他们说我不应该这么做,也许我不应该这么做好。。。实际上,它不完全是一个构造函数。。。它调用另一个第三方库,在这里我将类型作为一个简单的类型参数,然后构造对象。。。但无论如何,这些都是不必要的细节呸。所以不仅仅是我!:)是的,但包含此警告详细信息的MSDN页面明确声明“您不应抑制此警告”。老实说,我比FXCop团队的集体智慧更聪明吗?
public static T CreateInstance<T>()
public static void GenericMethod<T>(List<T> arg);
public void LinkedList<T> Slice<T>(LinkedList<T> collection, Predicate<T> match)
{
    ...
}