导出 (0) 打印
全部展开
信息
您所需的主题如下所示。但此主题未包含在此库中。

处理 Windows Phone 8 和 Windows 8 平台差异

2014/6/18

在一些情况下,您的代码起初看起来与本节所描述的共享技术并不十分匹配,因为您需要实现特定于一个平台的功能。但是经过一些重构后,您可以使用以下其中一种常规编码技术共享通用代码,然后专用化。

本主题包括以下部分。

针对各平台,有时您的 Windows Phone 8 和 Windows 8 应用的应用逻辑需要以稍微不同的方式实现。在这种情况下,您可以定义指令,为 Windows Phone 8 编译一个代码路径,为 Windows 8 编译另一个代码路径。该技术无法很好地扩展,创建出的代码可能较难维护,但是当您不想实现任何其他共享模式时,它将很有用。有关更多信息,请参见使用预处理器指令进行条件编译

在 .NET Framework 中,您可以将类、接口或结构拆分为分部类,这些分部类是多个文件,每一个文件实现类的一部分。


namespace ProjectB
{
    public class MyClass
    {
        public void CommonMethodA()
        {
            // code that is common to Windows Phone 8 and Windows 8
        }
 
        public int CommonMethodB()
        {
            int result = 0;
 
            // code that is common to Windows Phone 8 and Windows 8
 
            return result;
        }
 
        public void PlatformSpecificMethod()
        {
            // code that must be written for each platform
        }
    }
}


在此代码示例中,有一个需要专为 Windows Phone 8 和 Windows 8 实现的方法。如果代码依赖特定于平台的 API,则这可能是必需的。 我们可以重构代码,使一个分部类实现通用代码,另一个实现特定于平台的代码。下面的代码示例演示如何执行此操作。请注意下面的 partial 关键字的使用。该 partial 类定义可以跨两个应用共享的方法。我们可以将该类保存至项目文件夹外的通用共享文件夹,然后使用“添加为链接”将其添加至每一个项目。文件只编写一次,但是在两个应用间共享。


 
namespace App.Linked
{
    public partial class MyClass
    {
        public void CommonMethodA()
        {
            // code that is common to Windows Phone 8 and Windows 8
        }
 
        public int CommonMethodB()
        {
            int result = 0;
 
 
            // code that is common to Windows Phone 8 and Windows 8
 
            return result;
        }
 
    }
}


然后我们在每一个项目中创建新的类,然后在该类中实现特定于平台的代码。


namespace ProjectB
{
    public partial class MyClass
    {
        public void PlatformSpecificMethod()
        {
            // code that must be written for each platform
        }
    }
}


这是从托管代码中提取通用功能并实现面向各平台的特定于平台的代码的直接方式。如果通用代码的数量大于特定于平台的代码的数量,则该代码共享方法非常有用。关于该方法需要注意的一点是,您无法指定每一个特定于平台的分部类应实现什么。分离的能力可能有利,也可能有害。编译器将捕捉您错过方法实现的情况,但在设计时没有协定。有关使用分部类的更多信息,请参见分部类和方法(C# 编程指南)Partial (Visual Basic)

当您在两个类中有通用代码,而且两个可能都属于通用类型时,您可以创建父(或基础)类,并把通用代码移至该类。这样您可以消除重复代码。当您不能控制类的源代码,但是仍想添加或更改一些行为时,基类的另一个用处在于可扩展性。您可以使用继承,并重写特定的方法。对于我们的应用,我们的代码是通用的,但是仍需要针对每个平台实现类的特定部分。 您可以使用与上一节相同的类实现这一点。


namespace ProjectB
{
    public class MyClass
    {
        public void CommonMethodA()
        {
            // code that is common to Windows Phone 8 and Windows 8
        }
 
        public int CommonMethodB()
        {
            int result = 0;
 
            // code that is common to Windows Phone 8 and Windows 8
 
            return result;
        }
 
        public void PlatformSpecificMethod()
        {
            // code that must be written for each platform
        }
    }
}


这次我们将重构以定义基类。


namespace ProjectB
{
    public abstract class MyBaseClass
    {
        public void CommonMethodA()
        {
            // code that is common to Windows Phone 8 and Windows 8
        }
 
        public int CommonMethodB()
        {
            int result = 0;
 
            // code that is common to Windows Phone 8 and Windows 8
 
            return result;
        }
 
   public abstract void PlatformSpecificMethod();
    }
}


这是抽象类,所以它不能被实例化。相反,必须定义从该基类派生的类。还请注意,现在我们需要在两个平台上都实现的方法在基类中定义为抽象方法。它必须在派生类中实现。可以使用“添加为链接”,将基类作为链接文件与每个应用项目共享。它只编写一次,然后在项目间共享。 另一个选择是将该类添加至可移植类库,然后在应用之间共享这一对。有关使用可移植类库共享的更多信息,请参见使用可移植类库共享功能。定义基类之后,我们可以从中派生出特定于平台的类,并在该类中实现特定于平台的功能。


public class MyWin8Class : MyBaseClass
{
    public override void PlatformSpecificMethod()
    {
        // Implement this method specific to Windows 8
    }
}
 
public class MyWP8Class : MyBaseClass
{
    public override void PlatformSpecificMethod()
    {
        // Implement this method specific to Windows Phone 8
    }
}


您可以看到,我们已经在每一个项目中实现了从基类派生的类,而且实现了特定于平台的方法。有关使用抽象类的更多信息,请参见抽象类、密封类和类成员(C# 编程指南)MustInherit (Visual Basic)

当您需要运行时多态性时,接口将很有用。接口的目的是定义功能,以便您可以有对它的多个实现。 在使用功能的代码中,您可以只是引用接口而非具体的实现。无需知道是什么实现,您就可以调用接口的方法。我们使用类似于上例中已经使用的代码修改类,以创建将接口作为参数的构造函数。我们将该参数分配给名为 _platformImpl 的类成员。然后,在我们的 PlatformSpecificMethod 调用中,我们仅仅是在接口上调用该方法。


namespace ProjectB
    {
        public interface IPlatformSpecificCode
        {
            void PlatformSpecificMethodImpl();
        }

        public class MyClass
        {
            private IPlatformSpecificCode _platformImpl;

            public MyClass(IPlatformSpecificCode platformImpl)
            {
                _platformImpl = platformImpl;
            }

            public void CommonMethodA()
            {
                // code that is common to Windows Phone 8 and Windows 8
            }

            public int CommonMethodB()
            {
                int result = 0;

                // code that is common to Windows Phone 8 and Windows 8

                return result;
            }

            public void PlatformSpecificMethod()
            {
                _platformImpl.PlatformSpecificMethodImpl();
            }
        }

        // Windows 8 app project
        public class MyWin8Implementation : IPlatformSpecificCode
        {

            public void PlatformSpecificMethod()
            {
                // Implemented for Windows 8
            }
        }

        // Windows Phone 8 app project
        public class MyWP8Implementation : IPlatformSpecificCode
        {

            public void PlatformSpecificMethod()
            {
                // Implemented for Windows Phone 8
            }
        }

在此代码中,我们在每一个应用项目中实现接口,而且在项目中的某处构建 MyClass 并在实现中传递。以下代码段演示了这种情况。


            // Construct MyClass, passing in the Windows 8 implementation of the interface
            MyClass myClass = new MyClass(new MyWin8Implementation());

           // Construct MyClass, passing in the Windows Phone 8 implementation of the interface
            MyClass myClass = new MyClass(new MyWP8Implementation());

使用接口注入与平台相关的代码是非常强大的模式,在此简单基础上创建出了更为复杂的模式。服务定位符、工厂和依赖项注入、控制反转 (IoC) 和使用 IoC 容器的依赖项注入都是基于该概念的著名模式。许多提供这些模式的实现的第三方工具箱和框架可用。结合 MVVM 使用,它们形成非常强大的共享实现和注入专用化(需要时)的方式。

使用接口的另一个优点是单元测试更简单。为在类中执行代码而编写的单元测试可以模拟接口实现,向测试中注入可预测行为,或通过实现接口使单元测试不需要服务、数据连接或其他依赖项,从而简化测试。

Microsoft 正在进行一项网上调查,以了解您对 MSDN 网站的意见。 如果您选择参加,我们将会在您离开 MSDN 网站时向您显示该网上调查。

是否要参加?
显示:
© 2014 Microsoft