通过事件聚合器进行C#7和元组转换

通过事件聚合器进行C#7和元组转换,c#,.net,tuples,C#,.net,Tuples,在C#7中,元组变得强大: var tuple = (speed: 45, color: "red"); 与事件聚合器结合使用: EvtAgreg.Publish("SomeInfo", ( speed: 45, color: "red", )); 这将是非常强大的去耦代码。然而,从我收集到的信息来看,似乎不可能重铸这一点 EvtAgreg.Subscribe("SomeInfo", this.GetTy

在C#7中,元组变得强大:

var tuple = (speed: 45, color: "red");
与事件聚合器结合使用:

        EvtAgreg.Publish("SomeInfo", (
            speed:     45,
            color: "red",
        ));
这将是非常强大的去耦代码。然而,从我收集到的信息来看,似乎不可能重铸这一点

EvtAgreg.Subscribe("SomeInfo", this.GetType().Name, (obj) => {
       var data = ((int, string)) obj;
}
然而,这是不灵活的,我想知道是否有其他类似于JS的方式在运行时强制转换

EvtAgreg.Subscribe("SomeInfo", this.GetType().Name, (obj) => {
       var data = (?) obj;
       data.speed ... or data["speed"]       
}
显然,这是不可能的,但是,它是通过一个持有元组及其格式(Type)的类实现的吗


编辑:试图澄清问题

这不是关于铸造,而是如何使铸造简单

关键是,如果你有一个复杂的数据集,比如说20个值,可以是不同的类型,那么转换就变成了这样

var x = ((string, int, int, int, float, string, string, int, int, int, string, int, int, int, float, string, string, int, int, int)) obj;
这就不可能维持下去了

下面是一种使用Hashtable实现类似功能的方法:

出版商:

            MessageManager.Publish("Hardware_NewIRInfos",
                new Hashtable() {
                {   "position", i },
                {   "status",   (int)Load.IRStatus(i) },
                {   "serial",   (int)Load.IRSerial(i) },
                {   "id",       (int)Load.IRID(i) },
                {   "version",  Load.IRVersion(i) },
                {   "cal",      (int)Load.IRCalDate(i) },
                {   "emissivity",    Load.IREmissivity(i) },
                {   "transmissivity",Load.IRTransmissivity(i) },
                {   "gain",     Load.IRGain(i) },
                {   "offset",   Load.IROffset(i) }
            });
订户:

    MessageManager.Subscribe("Hardware_NewIRInfos", this.GetType().Name, (obj) =>
    {
        Hashtable data = (Hashtable)obj;

        IRSensorParameters[pos ].Channel = pos;
        IRSensorParameters[pos ].Status  = (int) data["status"];
        IRSensorParameters[pos ].ID      = (int)data["id"]; ;
        IRSensorParameters[pos ].Serial  = (int) data["serial"]; 
        IRSensorParameters[pos ].Version = (string)data["version"]; 
        IRSensorParameters[pos ].CalibrationDate = (int) data["cal"]; 
        IRSensorParameters[pos ].Emissivity = (float)data["emissivity"]; 
        IRSensorParameters[pos ].Transmissivity = (float)data["transmissivity"]; 
        IRSensorParameters[pos ].Gain = (float)data["gain"]; 
        IRSensorParameters[pos ].Offset = (float)data["offset"]; 
    });
在这里你仍然有静态铸造,但它更容易维护


使用C#7元组是否可能有一种类似的更好的方法?

您缺少一组括号:

var data = ((int, string)) obj;
你可以这样想: 要进行转换,请编写
(MyType)obj
,因此转换需要一组括号

要声明元组,您需要编写
(int,string)
,因此它需要自己的一组括号

它不能是同一组括号,因此会得到双括号


只要内部类型匹配,就可以强制转换为所需的任何命名属性:

var a = ((int speed, string color))(3,"red");
var c = ((int someInt, string someString))a;
var color = c.someString;

此外,您还可以始终使用通用名称
Item1
Item2
,它们不是由intellisense提示的,而是有效的。没有(简单的)方法将其转换为数组,但无论哪种方法都有常量,所以这应该很好

还有一件好事是元组扩展,您只需在一行中将其卸载到变量:

var tuple =(speed: 4, color: "red");
var (number, text) = tuple;

所以是的,元组很难很快将你团团转。我只将它们用于方法之间的私有类内通信,因为它不需要正式的类型声明。将tuple与20个项一起使用是错误的。不要那样做。在我看来,tuple中的4项太多了,需要专门创建类型。如果你真的想要这种非常脆弱的设置,你可以完全按照你写的
哈希表
是有效的c#类那样使用你的代码。我只需要创建专用类型


所以底线是不,你不能使用元组创建专用类或使用已经定义的类型-无论
IRSensorParameters[pos]
中有什么。为了避免依赖关系,您可以发送包含数据的字符串,例如json格式。

您缺少一组括号:

var data = ((int, string)) obj;
你可以这样想: 要进行转换,请编写
(MyType)obj
,因此转换需要一组括号

要声明元组,您需要编写
(int,string)
,因此它需要自己的一组括号

它不能是同一组括号,因此会得到双括号


只要内部类型匹配,就可以强制转换为所需的任何命名属性:

var a = ((int speed, string color))(3,"red");
var c = ((int someInt, string someString))a;
var color = c.someString;

此外,您还可以始终使用通用名称
Item1
Item2
,它们不是由intellisense提示的,而是有效的。没有(简单的)方法将其转换为数组,但无论哪种方法都有常量,所以这应该很好

还有一件好事是元组扩展,您只需在一行中将其卸载到变量:

var tuple =(speed: 4, color: "red");
var (number, text) = tuple;

所以是的,元组很难很快将你团团转。我只将它们用于方法之间的私有类内通信,因为它不需要正式的类型声明。将tuple与20个项一起使用是错误的。不要那样做。在我看来,tuple中的4项太多了,需要专门创建类型。如果你真的想要这种非常脆弱的设置,你可以完全按照你写的
哈希表
是有效的c#类那样使用你的代码。我只需要创建专用类型


所以底线是不,你不能使用元组创建专用类或使用已经定义的类型-无论
IRSensorParameters[pos]
中有什么。为了避免依赖关系,您可以发送包含数据的字符串,例如json格式。

只需为其创建一个类型,就不会出现任何强制转换问题;)类型是使用c的原因#创建类型然后创建代码依赖关系,这就是使用元组而不是模型的意义,否则只能创建类,这是我试图避免的。元组也是依赖关系(隐藏依赖关系,更糟糕)。类型可以在共享库中并位于一个位置,因此发布者和订阅方不需要“了解”彼此。是的,但他们都需要了解共享库,以便在共享库中创建耦合。为什么不将其序列化为json,作为字符串传递,然后在订阅方反序列化;)只需为它创建一个类型,就不会有任何铸造问题;)类型是使用c的原因#创建类型然后创建代码依赖关系,这就是使用元组而不是模型的意义,否则只能创建类,这是我试图避免的。元组也是依赖关系(隐藏依赖关系,更糟糕)。类型可以在共享库中并位于一个位置,因此发布者和订阅方不需要“了解”彼此。是的,但他们都需要了解共享库,以便在共享库中创建耦合。为什么不将其序列化为json,作为字符串传递,然后在订阅方反序列化;)是的,它确实需要一组括号(问题编辑)。然而,这个答案并没有解决这个问题。@Damien这就是你想要的吗?如果不是,你需要重新表述问题。我的问题是关于动态或清晰投射的,我将尝试用一个例子重新表述。是的,它确实需要一组括号(问题编辑)。然而,这个答案并没有解决这个问题。@Damien这就是你想要的吗?如果不是,你需要重新措辞这个问题。我的问题是关于动态的,或清晰的铸造,我会尝试用一个例子来重新措辞。