我已经明确定义的方法没有扩展方法

时间:2015-03-14 19:50:38

标签: c# windows-phone-8 extension-methods assembly-references

我试图编写一个只在地图上绘制圆圈的功能。我基本上遵循here给出的代码。这是我的实际代码:

using attempt2.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Device.Location;
using System.Windows;
using Windows.Foundation;
using Windows.UI.Xaml.Controls.Maps;
using Windows.Devices.Geolocation;
using Windows.Services.Maps;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Shapes;
using System.Device.Location;

namespace attempt2
{
    class MapsClass
{

    //computes a point on the perimeter given an arbitrary point and distance

    public GeoCoordinate getDistanceBearing(this GeoCoordinate point, double distance, double bearing = 180)
    {
        double radius = Convert.ToDouble(this.Set.container.Values["Radius"]);

        const double degreestoRadian = Math.PI / 180;
        const double radiantoDegrees = 180 / Math.PI;
        const double earthRadius = 6378137.0;

        var latA = point.Latitude * degreestoRadian;
        var longA = point.Longitude * degreestoRadian;
        var angularDistance = distance / earthRadius;
        var trueCourse = bearing * degreestoRadian;

        var lat = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

        var dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
            Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

        var lon = ((longA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

        var result = new GeoCoordinate(lat * radiantoDegrees, lon * radiantoDegrees);

        return result;
    }

    //adds up a series of those points to create a circle

    public static IList<GeoCoordinate> GetCirclePoints(this GeoCoordinate center,
                               double radius, int nrOfPoints = 50)
    {
        var angle = 360.0 / nrOfPoints;
        var locations = new List<GeoCoordinate>();
        for (var i = 0; i <= nrOfPoints; i++)
        {
            locations.Add(center.getDistanceBearing(radius, angle * i));
        }
        return locations;
    }

    //draws the circle on the map

    private void MainPageLoaded()
    {
        if (this.Data.CurrentOrNot == false)     //searched location
        {
            var location = this.Data.SearchedLocation;
            Map.Center = location;
            Map.ZoomLevel = 16;

            var fill = Windows.UI.Color.FromArgb(50, 100, 0, 100);
            var stroke = Windows.UI.Color.FromArgb(150, 250, 0, 0);
            fill.A = 80;
            stroke.A = 80;
            var circle = new MapPolygon
            {
                StrokeThickness = 2,
                FillColor = fill,
                StrokeColor = stroke,
                StrokeDashed = false,
            };

            foreach (var p in location.GetCirclePoints(150))
            {
                circle.Path.Add(p);
            }

            Map.MapElements.Add(circle);


        } else
        {
            var location = this.Data.CurrentLocation;
            Map.Center = location;
            Map.ZoomLevel = 16;

            var fill = Windows.UI.Color.FromArgb(50, 100, 0, 100);
            var stroke = Windows.UI.Color.FromArgb(150, 250, 0, 0);
            fill.A = 80;
            stroke.A = 80;
            var circle = new MapPolygon
            {
                StrokeThickness = 2,
                FillColor = fill,
                StrokeColor = stroke,
                StrokeDashed = false,
            };

            foreach (var p in location.GetCirclePoints(150))
            {
                circle.Path.Add(p);
            }

            Map.MapElements.Add(circle);

        }         

    }

当我调用其中一种方法时,我所遇到的唯一错误就在于这一行,特别是行locations.Add(center.getDistanceBearing(radius, angle * i));以及foreach (var p in location.GetCirclePoints(150))的两个实例。 Visual Studio给了我错误

  

&#39; System.Device.Location.GeoCoordinate&#39;不包含&#39; getDistanceBearing&#39;的定义并且没有延伸方法&#39; getDistanceBearing&#39;接受类型为#System; Device.Location.GeoCoordinate&#39;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

和我引用GetCirclePoints时完全相同类型的错误。但是,当我已经定义了方法时,为什么它会给我这些错误?为什么基本上相同的代码显然适用于我提供的示例?

2 个答案:

答案 0 :(得分:0)

扩展方法应该是static

中的static方法

MapsClassgetDistanceBearing不是静态的

您可以将您的方法用作常用方法

答案 1 :(得分:0)

您没有遵循扩展方法的规则。 这些类和方法也必须标记为静态。 一个简单的例子:

public static class Extension
{
    const string _DefaultBasePath = @"C:\Users\stuyckp\Documents\Visual Studio 2013\Projects\WPF\Interstone";
    private static string _BasePath = null;
    public static string getFullPath(this string relativePath)
    {
        if (relativePath == null) return null;
        string path = BasePath;
        if (!path.EndsWith("\\") && !relativePath.StartsWith("\\")) path += "\\";
        return path + relativePath;
    }

    static private string BasePath
    {
        get
        {
            if (_BasePath != null) return _BasePath;

            try
            {
                Configuration cs = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                ConfigurationSectionGroup g = cs.SectionGroups["applicationSettings"];
                ClientSettingsSection s
                    = (from ConfigurationSection section in g.Sections
                        where section is ClientSettingsSection
                        select section).FirstOrDefault() as ClientSettingsSection;
                _BasePath = s.Settings.Get("BasePath").Value.ValueXml.InnerText;
            }
            catch
            {
                _BasePath = _DefaultBasePath;
            }

            return _BasePath;
        }
    }
}

不要将任何内容组合在一起,只能将这些静态类用于扩展方法本身所需的代码。这有效地使类中的所有内容成为静态:私有变量,辅助方法,......

所以你需要这样的东西:

public static class MapsClass{
//computes a point on the perimeter given an arbitrary point and distance

public static GeoCoordinate getDistanceBearing(this GeoCoordinate point, double distance, double bearing = 180)
{
    double radius = Convert.ToDouble(this.Set.container.Values["Radius"]);

    const double degreestoRadian = Math.PI / 180;
    const double radiantoDegrees = 180 / Math.PI;
    const double earthRadius = 6378137.0;

    var latA = point.Latitude * degreestoRadian;
    var longA = point.Longitude * degreestoRadian;
    var angularDistance = distance / earthRadius;
    var trueCourse = bearing * degreestoRadian;

    var lat = Math.Asin(Math.Sin(latA) * Math.Cos(angularDistance) + Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));

    var dlon = Math.Atan2(Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA),
        Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));

    var lon = ((longA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

    var result = new GeoCoordinate(lat * radiantoDegrees, lon * radiantoDegrees);

    return result;
}

//adds up a series of those points to create a circle

public static IList<GeoCoordinate> GetCirclePoints(this GeoCoordinate center,
                           double radius, int nrOfPoints = 50)
{
    var angle = 360.0 / nrOfPoints;
    var locations = new List<GeoCoordinate>();
    for (var i = 0; i <= nrOfPoints; i++)
    {
        locations.Add(center.getDistanceBearing(radius, angle * i));
    }
    return locations;
}