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 { .... }