gpt4 book ai didi

c# - 通过强制转换或鸭式输入不同的对象类型来重用相同的功能

转载 作者:太空宇宙 更新时间:2023-11-03 12:25:35 25 4
gpt4 key购买 nike

在 .NET 应用程序中,我正在使用两个远程 WCF 服务,它们都具有“相同”对象的定义:CoreService.CustomerProductService.Customer .

“相同”特意放在引号里;从 namespace 的角度来看,它们是两个不同的实体。然而,这是纯粹的,因为服务的生成/使用方式。在这种情况下,两个对象都来自后端系统中的同一个库是一个给定的事实。

在特定情况下,我需要从两种对象类型中提取内容。我有一个最初为一个特定实例构建的函数:

private static string _ExtractFoo(CoreService.Customer customer) {
// removed for the sake of brevity
return string.Empty;
}

我想要的实际上是重用相同的操作,通过提供重载和强制转换或装箱的方式简单地尝试说服编译器和运行时这将正常工作(如果愿意,可以简单地考虑 duck typing)。

以下情况不起作用:

private static string _ExtractFoo(ProductService.Customer customer) {

// #1 - Cast, results in error:
// Cannot convert type ... via a built-in conversion
return _ExtractFoo((CoreService.Customer) customer);

// #2 - Safe cast, results in error:
// Cannot convert type ... via a built-in conversion
return _ExtractFoo(customer as CoreService.Customer);

// #3 - Works for compiler, breaks at runtime where 'casted' is null
dynamic d = customer;
var casted = d as CoreService.Customer;
return _ExtractFoo(casted);
}

一个有效的简单修复方法是首先序列化为 json:

private static string _ExtractFoo(ProductService.Customer customer) {
// awkward hack - but it blends!
var serialized = JsonConvert.SerializeObject(customer);
var deserialized = JsonConvert.DeserializeObject<CoreService.Customer>(serialized);

return _ExtractFoo(deserialized);
}

事实上,考虑到两个对象的属性和值保证匹配,这样做是有道理的。尽管如此,这很昂贵而且似乎完全没有必要。

另一种选择是使用 implicit conversion operator .但是,考虑到对象是服务生成的,我不太了解如何使用运算符扩展这两个对象。

要点不是争论这是否是最佳实践。也不知道如何找到替代方案,例如在不同服务引用之间重用相同的共享对象。我很清楚这个 hack 的尴尬。可以说,从语言的角度来看,我发现这是一个有趣的挑战。

这让我想到了真正的问题:是否有一种更优雅的方式来欺骗编译器接受这个,或者,更好地说,在两个“不同但相同”的对象,允许我重用 _ExtractFoo() 实现?

更新 I - 让外部网络服务使用通用接口(interface)不是一种选择。另外,最好知道 Customer 对象具有相当深的嵌套属性和子对象层次结构;使用 AutoMapper 之类的工具或手动 map 会很麻烦(更不用说容易出错)。

更新 II - 为了将来引用,我试图解释我的问题/疑问是如何修改 _ExtractFoo() 方法 - 或其实现- 因此它可以应用于 CoreService.CustomerProductService.Customer(考虑到上述所有内容)。在“请列出所有其他选择”的意义上,它绝对不是一个开放性问题,尽管在我看来作为答案提供的内容肯定是可行的。

最佳答案

在我的脑海中,你的选择是:

  1. 获取两个源类来实现相同的接口(interface)并传递它而不是传递具体类型。这将是更好的选择,但我猜这里不可能。
  2. 反序列化和反序列化以在类型之间进行转换。您已经有了这段代码,但正如您所说,它可能很慢。
  3. 使用映射库,例如 AutoMapper在类型之间进行转换。这非常快,但需要您从 Nuget 引入外部库(我已经多次使用 AutoMapper)
  4. 自己手动映射属性。这可能是最快的代码,但写起来非常糟糕。
  5. 在整个链中使用dynamic,而不仅仅是在顶部。你失去了编译时类型检查,但它应该相当快。例如,而不是像这样的功能:

    public static string _ExtractFoo(ProductService.Customer customer)
    {
    return customer.DoSomethingExciting();
    }

    你会有这个:

    public static string _ExtractFoo(dynamic customer)
    {
    return customer.DoSomethingExciting();
    }

    如果需要,您可以添加一些检查以确保 customerProductService.CustomerCoreService.Customer(如果需要)一些安全。

关于c# - 通过强制转换或鸭式输入不同的对象类型来重用相同的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45217577/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com