C# 通用函数接受类型参数<;T<;U>>;?

C# 通用函数接受类型参数<;T<;U>>;?,c#,C#,我正在重构以下代码,以使用泛型来减少这些方法: class CInt { public int P1 { get; set; } } class CDate { public DateTime P1 { get; set; } } class CStr { public string P1 { get; set; } } static IEnumerable<CInt> Fun(IEnumerable<CInt> p) { .... } static IEnume

我正在重构以下代码,以使用泛型来减少这些方法:

class CInt  { public int P1 { get; set; } }
class CDate { public DateTime P1 { get; set; } }
class CStr  { public string P1 { get; set; } }

static IEnumerable<CInt>  Fun(IEnumerable<CInt> p) { .... }
static IEnumerable<CDate> Fun(IEnumerable<CDate> p) { .... }
static IEnumerable<CStr>  Fun(IEnumerable<CStr> p) { .... }
或者这不可能,除非C#支持更高级的类型

不确定“除非C#支持更高阶类型”是什么意思,但一种可能的解决方案是让
IBase
扩展一个非泛型
IBase
,并将其用于约束
Fun

interface IBase { }
interface IBase<T> : IBase { T P1 { get; set; } }

static IEnumerable<T> Fun<T>(IEnumerable<T> p) where T : IBase { .... }
接口IBase{}
接口IBase:IBase{tp1{get;set;}
静态IEnumerable Fun(IEnumerable p),其中T:IBase{..}
当然,如果在
Fun
中使用
IBase
的泛型类型,则必须将is声明为第二个泛型参数

不确定“除非C#支持更高阶类型”是什么意思,但一种可能的解决方案是让
IBase
扩展一个非泛型
IBase
,并将其用于约束
Fun

interface IBase { }
interface IBase<T> : IBase { T P1 { get; set; } }

static IEnumerable<T> Fun<T>(IEnumerable<T> p) where T : IBase { .... }
接口IBase{}
接口IBase:IBase{tp1{get;set;}
静态IEnumerable Fun(IEnumerable p),其中T:IBase{..}

当然,如果在
Fun
中使用
IBase
的泛型类型,则必须将is声明为第二个泛型参数

在我看来,问题是这个没有多大用处。。。根据
T
,对
U
的语义解释是什么。既然你对
t
一无所知,那就毫无意义了。
U
到底发生了什么?如果您只需要一个类型,您可以尝试使用反射并拉取
T
IBase
接口的第一个泛型类型。您的最后一行很接近-只需将
Fun
更改为
Fun
。如果您只有三件事,那么只需编写三个方法来处理这三件事。当您希望能够编写任何类型的内容时,请使用泛型。你想要一个函数列表,一个苹果列表,一个矩形列表,所以这个列表是通用的。如果你只想享受整数、布尔和字符串的乐趣,那就继续使用你现有的代码。@EricLippert我将有大约六种情况,可能更多-取决于基本数据类型。在我看来,问题是这没有多大用处。。。根据
T
,对
U
的语义解释是什么。既然你对
t
一无所知,那就毫无意义了。
U
到底发生了什么?如果您只需要一个类型,您可以尝试使用反射并拉取
T
IBase
接口的第一个泛型类型。您的最后一行很接近-只需将
Fun
更改为
Fun
。如果您只有三件事,那么只需编写三个方法来处理这三件事。当您希望能够编写任何类型的内容时,请使用泛型。你想要一个函数列表,一个苹果列表,一个矩形列表,所以这个列表是通用的。如果你只想享受整数、布尔值和字符串的乐趣,那就继续使用你现有的代码。@EricLippert我将有大约六种情况,可能更多-取决于基本数据类型。如果函数需要访问正文中t的
P1
,这将不起作用。我已经用一些访问代码的示例更新了这个问题。就像我最后一句话所说的,如果您的内部代码取决于
U
的类型(即使像您这样间接调用其他泛型函数),那么您必须将其添加为泛型参数。如果函数需要访问正文中t的
P1
,这将不起作用。我已经用一些示例访问代码更新了这个问题。就像我最后一句话所说的,如果您的内部代码取决于
U
的类型(即使像您这样间接地调用其他通用函数),那么您必须将其添加为通用参数。
interface IBase { }
interface IBase<T> : IBase { T P1 { get; set; } }

static IEnumerable<T> Fun<T>(IEnumerable<T> p) where T : IBase { .... }