有可能得到你在问题中显示的语法,但你必须非常聪明才能做到这一点。
让我们更具体地设置问题。我认为这里的关键点是语法。我们想要这个:
int intValue = GetData();
string stringValue = GetData();
DateTime[] dateTimeArrayValue = GetData();
但是,我们不希望这样做:
double doubleValue = GetData();
DateTime? nullableDateTimeValue = GetData();
为了实现这一点,我们必须在来自GetData() 的返回值中使用一个中间对象,其定义如下所示:
public class Data
{
public int IntData { get; set; }
public string StringData { get; set; }
public DateTime[] DataTimeArrayData { get; set; }
public MultiReturnValueHelper<int, string, DateTime[]> GetData()
{
return new MultiReturnValueHelper<int, string, DateTime[]>(
this.IntData,
this.StringData,
this.DataTimeArrayData);
}
}
当然,您的实现会完全不同,但这样就可以了。现在让我们定义MultiReturnValueHelper。
public class MultiReturnValueHelper<T1, T2, T3> : Tuple<T1, T2, T3>
{
internal MultiReturnValueHelper(T1 item1, T2 item2, T3 item3)
: base(item1, item2, item3)
{
}
public static implicit operator T1(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item1;
}
public static implicit operator T2(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item2;
}
public static implicit operator T3(MultiReturnValueHelper<T1, T2, T3> source)
{
return source.Item3;
}
}
对于一般情况,对 T1、T2、T3 等重复此定义。
您还可以将返回值帮助器非常紧密地绑定到返回它的类或方法,使您能够为索引器创建同样的效果,您可以在其中获取和分配一组离散的类型。这就是我发现它最有用的地方。
另一个应用程序是启用如下语法:
data["Hello"] = "World";
data["infamy"] = new DateTime(1941, 12, 7);
data[42] = "Life, the universe, and everything";
完成此语法的精确机制留给读者作为练习。
对于这个问题的更通用的解决方案(我认为这与歧视联合问题相同),请参阅my answer to that question。