C#泛型中的void?
我有一个接受请求并提供响应的通用方法C#泛型中的void?,c#,generics,C#,Generics,我有一个接受请求并提供响应的通用方法 public Tres DoSomething<Tres, Treq>(Tres response, Treq request) {/*stuff*/} 公共Tres剂量测量(Tres响应、Treq请求) {/*东西*/} 但我并不总是希望请求得到响应,也不总是希望通过提供请求数据来获得响应。我也不想为了做一些小的改变而不得不复制和粘贴整个方法。我想要的是能够做到这一点: public Tre DoSomething<Tres>(
public Tres DoSomething<Tres, Treq>(Tres response, Treq request)
{/*stuff*/}
公共Tres剂量测量(Tres响应、Treq请求)
{/*东西*/}
但我并不总是希望请求得到响应,也不总是希望通过提供请求数据来获得响应。我也不想为了做一些小的改变而不得不复制和粘贴整个方法。我想要的是能够做到这一点:
public Tre DoSomething<Tres>(Tres response)
{
return DoSomething<Tres, void>(response, null);
}
公共Tre剂量测量(Tre响应)
{
返回剂量测量(响应,空);
}
这在某种程度上可行吗?具体使用void似乎不起作用,但我希望找到类似的方法。
void
,虽然是一种类型,但仅作为方法的返回类型有效
无法绕过
void
void
的限制,尽管类型仅作为方法的返回类型有效
没有办法绕过
void
的这个限制,你不能使用void
,但是你可以使用object
:这是一个小小的不便,因为你想要的void
函数需要返回null
,但是如果它统一了你的代码,那么付出的代价应该很小
无法将
void
用作返回类型,这至少部分导致了Func
和Action
泛型委托族之间的分裂:如果能够返回void
,所有Action
都将变成Func
。不幸的是,这是不可能的。您不能使用void
,但您可以使用对象
:这是一个小小的不便,因为您想要的-void
函数需要返回null
,但是如果它统一了您的代码,那么付出的代价应该很小
无法将
void
用作返回类型,这至少部分导致了Func
和Action
泛型委托族之间的分裂:如果能够返回void
,所有Action
都将变成Func
。不幸的是,这是不可能的。不,不幸的是不可能。如果void
是一种“真正的”类型(比如说),生活在很多方面都会简单得多。特别是,我们不需要同时使用Func
和Action
系列-只需要Func
而不是Action
,Func
而不是Action
等
它还将使异步更简单-根本不需要非泛型的任务
类型-我们只需要任务
不幸的是,这不是C#或.NET类型系统的工作方式…不,不幸的是不是。如果
void
是一种“真正的”类型(比如说),生活在很多方面都会简单得多。特别是,我们不需要同时使用Func
和Action
系列-只需要Func
而不是Action
,Func
而不是Action
等
它还将使异步更简单-根本不需要非泛型的任务
类型-我们只需要任务
不幸的是,这不是C#或.NET类型系统的工作方式…您可以像其他人建议的那样简单地使用
对象。或者Int32
,我已经看到了它的一些用途。使用Int32
引入了一个“虚拟”数字(使用0
),但至少不能将任何大的外来对象放入Int32
引用中(结构是密封的)
您也可以编写自己的“void”类型:
MyVoid
允许引用(它不是静态类),但只能是null
。实例构造函数是私有的(如果有人试图通过反射调用这个私有构造函数,就会向他们抛出异常)
由于引入了值元组(2017,.NET 4.7),使用(0元组,非泛型变量)而不是这样的MyVoid
可能是很自然的。它的实例有一个返回“()”
的ToString()
,因此它看起来像一个零元组。从当前版本的C#开始,您不能使用代码中的标记()
来获取实例。您可以使用default(ValueTuple)
或仅使用default
(当可以从上下文推断类型时)。您可以按照其他人的建议使用对象。或者Int32
,我已经看到了它的一些用途。使用Int32
引入了一个“虚拟”数字(使用0
),但至少不能将任何大的外来对象放入Int32
引用中(结构是密封的)
您也可以编写自己的“void”类型:
MyVoid
允许引用(它不是静态类),但只能是null
。实例构造函数是私有的(如果有人试图通过反射调用这个私有构造函数,就会向他们抛出异常)
由于引入了值元组(2017,.NET 4.7),使用(0元组,非泛型变量)而不是这样的MyVoid
可能是很自然的。它的实例有一个返回“()”
的ToString()
,因此它看起来像一个零元组。从当前版本的C#开始,您不能使用代码中的标记()
来获取实例。您可以使用default(ValueTuple)
或仅使用default
(当可以从上下文推断类型时)。以下是您可以执行的操作。正如@JohnSkeet所说的,C#中没有单位类型,所以自己制作吧
public sealed class ThankYou {
private ThankYou() { }
private readonly static ThankYou bye = new ThankYou();
public static ThankYou Bye { get { return bye; } }
}
现在,您可以始终使用Func
而不是Action
或者使用Rx团队已经制作的产品:以下是您可以做的。正如@JohnSkeet所说的,C#中没有单位类型,所以自己制作吧
public sealed class ThankYou {
private ThankYou() { }
private readonly static ThankYou bye = new ThankYou();
public static ThankYou Bye { get { return bye; } }
}
现在,您可以始终使用Func
而不是Action
或者用点什么
public ThankYou MethodWithNoResult() {
/* do things */
return ThankYou.Bye;
}
public sealed class Nothing {
public static Nothing AtAll { get { return null; } }
}
void myProcWithNoArguments(Nothing Dummy){
myProcWithNoArguments(){
}
void myProcWithNoArguments(Nothing Dummy=null){
...
}
public sealed class Void {
private Void() { }
}
public sealed class None {
private None() { }
}