如何跨命名空间和平台伪造库(GDI 到 Xamarin.Forms),例如重用 Color 结构
Posted
技术标签:
【中文标题】如何跨命名空间和平台伪造库(GDI 到 Xamarin.Forms),例如重用 Color 结构【英文标题】:How to fake a library (GDI to Xamarin.Forms) across namespaces and platforms such as reusing Color struct 【发布时间】:2016-09-27 02:49:09 【问题描述】:我试图在 Xamarin 中重用旧版 Windows GDI 代码而不修改旧版 GDI 代码(使用 #if 除外)。在这种特定情况下,我需要使用包装在我自己的颜色结构中的 Xamrin.Forms 中的颜色。我收到错误无法转换,如上面问题标题中发布的那样。
这是不被修改(或很少)的遗留代码
#if WINDOWS
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;
#else //if Xamarin
using FakeGDI; //cannot specify 'using Xamarin.Forms;' in legacy class
#endif
namespace LegacyCode
public class MyClass
public MyClass ()
Color x = Color.Yellow; //must not change legacy code
这是使旧版 GDI 调用适应 Xamarin.Forms 的代码
using System;
//cannot specify 'using Xamarin.Forms;' I want to fully qualify Xamarin.Forms as shown below 'Xamarin.Forms.Color.Yellow;'
namespace FakeGDI
public struct Color
public static Color Yellow
get
return Xamarin.Forms.Color.Yellow;
;
我正在寻找的解决方案是通过我的 Color 结构间接编译和使用 Xamarin.Forms Color 结构。
需要什么才能允许这种类型的转换?
我得到的错误是:无法隐式转换类型Xamarin.Forms.Color' to
FakeGDI.Color'
谢谢
【问题讨论】:
"不能指定'使用 Xamarin.Forms;'在遗留类中” - 为什么不呢? 请不要与其他用户串通,多次转发同一个问题。这被认为是 Stack Overflow 上的噪音。如果您的问题因无法回答或没有引起回复而关闭,那么首先要做的是改进问题;对此的一些指导是given here。低质量或无法回答的问题通常会被关闭,但如果改进或澄清(视情况而定)可以重新打开 (***.com/questions/37505910/?noredirect=1)。 【参考方案1】:在 C# 中绝对不可能做到这一点。
你正在尝试做的事情:
StructA a;
StructB b;
a = b;
In 永远无法工作。只有当 Color 是一个类时才有可能,那么你可以使用继承。
您不能指定“使用 Xamarin.Forms;”的约束在遗留类中并没有给你留下任何方法,因为与 javascript 等语言相比,你不能复制对类的引用,而只能复制到对象。
但是,一个解决方案可能是用不同的语言编写 FakeGDI,这确实允许复制对类的引用。
以下是如何在 JavaScript 中执行此操作的示例,虽然您不能真正在 JavaScript 中执行此操作,但您必须寻找一种可以将其模块保存为 DLL 的动态语言。
module FakeGDI
var Xamarin = require('Xamarin.Forms.Color.Yellow');
module.exports =
Color : Xamarin.Forms.Color
;
【讨论】:
【参考方案2】:您的代码需要将成员静态属性定义为正确的类型。换句话说:
namespace FakeGDI
public struct Color
public static Xamarin.Forms.Color Yellow
get
return Xamarin.Forms.Color.Yellow;
请注意,Xamarin.Forms
命名空间应用于静态属性本身。
【讨论】:
谢谢基思。我将它添加为“public static Xamarin.Forms.Color Yellow”,但它没有编译并给出了同样的错误。它为你编译了吗? 不,您的示例代码不足以重现问题(我不知道该代码预期在什么上下文中运行)。如果您可以将最小的复制项目推送到 github 存储库中,那么可能会提供更好的帮助。【参考方案3】:您看到的异常是因为您的静态属性 FakeGDI.Color.Yellow 的返回类型是 FakeGDI.Color,但您返回的是 Xamarin.Forms.Color 的实例。
首先,您希望静态属性返回您的 Color 类型的实例,因为这是您希望旧代码引用的 Color 类型。然后,您想要定义一个隐式操作符,它将您的 Color 类型转换为 Xamarin Color 类型,无论您的旧代码需要 Xamarin.Forms.Color 但它与您的 FakeGCI.Color 一起提供。
您可以使您的 Color 类型成为 Xamarin Color 类型的包装器,如下所示:
namespace FakeGDI
public struct Color
private Xamarin.Forms.Color xamarinColor;
public static Color Yellow
get
return new Color(Xamarin.Forms.Color.Yellow);
private Color(Xamarin.Forms.Color color)
this.xamarinColor = color;
public static implicit operator Xamarin.Forms.Color(Color color)
return color.xamarinColor;
// although serving no purpose in your snippet, your legacy code will
// likely need to cast from Xamarin Color to your Color type also
public static implicit operator Color(Xamarin.Forms.Color color)
return new Color(color);
【讨论】:
@Anna 很高兴为您提供帮助,如果您接受了我的回答,如果它解决了您的问题,将不胜感激 :) 使用 Xamarin.Forms.Color 使用我的 Color 结构是否涉及或调用装箱和拆箱?不只是在我的命名成员下传递值吗?谢谢 这不是装箱,装箱实际上是指将值类型转换为引用类型。我提供的几乎只是语法糖,让您的旧代码与您无法为其添加引用的 Xamarin.Forms.Color 很好地配合使用。编辑:注意颜色是一个结构以上是关于如何跨命名空间和平台伪造库(GDI 到 Xamarin.Forms),例如重用 Color 结构的主要内容,如果未能解决你的问题,请参考以下文章
如何跨 Namespace 同步 Secret 和 ConfigMap?