Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 根据C中具有无限组合的两个参数定义要使用的函数#_C#_Generics_Enums_Coordinate Transformation - Fatal编程技术网

C# 根据C中具有无限组合的两个参数定义要使用的函数#

C# 根据C中具有无限组合的两个参数定义要使用的函数#,c#,generics,enums,coordinate-transformation,C#,Generics,Enums,Coordinate Transformation,我有一个问题必须通过一个我不知道的设计模式来解决。这适用于不同坐标系之间的变换。我向你解释 1/我有一个引用系统集合(EPSG)的枚举: 这些枚举允许定义对象坐标使用的系统 public struct Coordinate {     public System system; public double X; public double Y; public double Z; } 可以有无限多个系统。枚举索引不一定相互跟随,也不能修改 2/对象必须能够从一个系统传递

我有一个问题必须通过一个我不知道的设计模式来解决。这适用于不同坐标系之间的变换。我向你解释

1/我有一个引用系统集合(EPSG)的枚举:

这些枚举允许定义对象坐标使用的系统

public struct Coordinate
{
    public System system;

    public double X;
    public double Y;
    public double Z;
}
可以有无限多个系统。枚举索引不一定相互跟随,也不能修改

2/对象必须能够从一个系统传递到另一个系统。我将转换从一个系统应用到另一个系统。系统A->系统B。 此转换不会更改类型。它会更改坐标(x、y和z)的值,以便该点位于正确的位置,具体取决于其系统

所有的组合都是可能的。但是,根据起动系统的不同,更换系统的计算结果并不总是相同的

3/I有几个包含转换方法的静态类:

public static class WGS84
{
    public static Coordinate ToNAD27 (double X, double Y, double Z)
    {
        ...
    }

    public static Coordinate ToNAD83 (double X, double Y, double Z)
    {
        ...
    }
}
我们来解决这个问题

4/为了定义使用了哪种转换并避免大量的转换,如果我第一次使用一个开关,将包含起始系统和到达系统的对象作为参数:

public class SystemTransform
{
    public System initial;
    public System terminal;
}


public struct Coordinate 
{
    public System system;

    public double X;
    public double Y;
    public double Z;


    public Coordinate Transform (SystemTransform s)
    {
        switch(s)
        {
            case SystemTransform st when st.Initial == System.WGS84 && st.Terminal == System.NAD27:
                        return WGS84.ToNAD27(X, Y, Z);

            ...

            case SystemTransform st when st.Initial == System.WGS84 && st.Terminal == System.Z:
                        throw new NotImplementedException ($ "{s} not implmented");
        }
    }
}
5/由于不切实际和美观,我转向一本字典:

public static class TransformWithDictionary
{
        private static Dictionary <SystemTransform, Func <Coordinate , Coordinate >> ParserMap = new Dictionary <SystemTransform, Func <Coordinate , Coordinate >>
        {
            {new SystemTransform (System.WGS84, System.NAD27), coord => WGS84.ToNAD27(coord)},
            {new SystemTransform (System.WGS84, System.NAD83), coord => WGS84.ToNAD83(coord)},
        };

        public MyObject GetParserFor (SystemTransform st, Coordinate coord)
        {
            if (! ParserMap.ContainsKey(st))
                throw new NotImplementedException ("Unexpected file type value" + st);

            return ParserMap[st](coord);
        }
}
公共静态类TransformWithDictionary
{
私有静态字典ParserMap=新字典
        {
{newsystemtransform(System.WGS84,System.NAD27),coord=>WGS84.ToNAD27(coord)},
{newsystemtransform(System.WGS84,System.NAD83),coord=>WGS84.ToNAD83(coord)},
        };
公共MyObject GetParserFor(SystemTransform st,坐标坐标坐标)
        {
如果(!ParserMap.ContainsKey(st))
抛出新的NotImplementedException(“意外的文件类型值”+st);
返回ParserMap[st](坐标);
        }
}
有点优雅,​​但这并不能解决问题

从理论上讲,我面临着一个转变∞ 可能性。只需说,不可能手动填充并随时间进行维护

第三个想法是建一个工厂。但这并不能帮助我根据来源系统和到达系统定义使用哪个函数


知道吗​​解决这个问题的设计模式?

我不确定我是否完全理解您的需求,但对我来说,简单的抽象就足够了

    public abstract class CoordinateSystem
    {
        public double X {get; private set; }
        public double Y {get; private set; }
        public double Z {get; private set; }

        protected CoordinateSystem( Double x, Double y, Double z )
        {
            X = x;
            Y = y;
            Z = z;
        }

        public abstract CoordinateSystemA ToA();
        public abstract CoordinateSystemB ToB();
        public abstract CoordinateSystemC ToC();
    }

    public class CoordinateSystemA : CoordinateSystem
    {
        public CoordinateSystemA( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(X,Y,Z);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(2,2,2);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(3,3,3);
        }
    }

    public class CoordinateSystemB : CoordinateSystem
    {
        public CoordinateSystemB( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(1,1,1);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(X,Y,Z);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(3,3,3);
        }
    }

    public class CoordinateSystemC : CoordinateSystem
    {
        public CoordinateSystemC( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(1,1,1);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(2,2,2);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(X,Y,Z);
        }
    }


    public static class Program {
        public static void Main() {
            CoordinateSystem coordinateSystem = new CoordinateSystemA(1,1,1);
            CoordinateSystem b = coordinateSystem.ToB();
            CoordinateSystem c = b.ToC();
        }
    }
通过放置
ToX()

如果这不能满足您的要求,我认为您应该看看访问者模式。它有点复杂,但有很多例子。

我不确定我是否完全理解您的需求,但对我来说,听起来简单的抽象就足够了

    public abstract class CoordinateSystem
    {
        public double X {get; private set; }
        public double Y {get; private set; }
        public double Z {get; private set; }

        protected CoordinateSystem( Double x, Double y, Double z )
        {
            X = x;
            Y = y;
            Z = z;
        }

        public abstract CoordinateSystemA ToA();
        public abstract CoordinateSystemB ToB();
        public abstract CoordinateSystemC ToC();
    }

    public class CoordinateSystemA : CoordinateSystem
    {
        public CoordinateSystemA( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(X,Y,Z);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(2,2,2);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(3,3,3);
        }
    }

    public class CoordinateSystemB : CoordinateSystem
    {
        public CoordinateSystemB( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(1,1,1);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(X,Y,Z);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(3,3,3);
        }
    }

    public class CoordinateSystemC : CoordinateSystem
    {
        public CoordinateSystemC( Double x, Double y, Double z )
          : base(x, y, z )
        {}

        public override CoordinateSystemA ToA() {
            return new CoordinateSystemA(1,1,1);
        }
        public override CoordinateSystemB ToB() {
            return new CoordinateSystemB(2,2,2);
        }
        public override CoordinateSystemC ToC() {
            return new CoordinateSystemC(X,Y,Z);
        }
    }


    public static class Program {
        public static void Main() {
            CoordinateSystem coordinateSystem = new CoordinateSystemA(1,1,1);
            CoordinateSystem b = coordinateSystem.ToB();
            CoordinateSystem c = b.ToC();
        }
    }
通过放置
ToX()

如果这不能满足您的要求,我认为您应该看看访问者模式。它有点复杂,但是有很多例子。

似乎
MyObject
是非常可变的,不是
struct
的好候选者。
case
语句似乎完全忽略了
开关
vairable
s
。这真的有效吗?如果你有不同的转换,并且这些转换必须手工编码,那么我没有得到“具有无限可能性的开关”语句,你仍然必须编写无限转换,那么重点在哪里呢?在
到系统结构b
到系统结构x
等中你有什么类型的代码?如果它们真的都不同,那么你的问题本质上是复杂的。我能想到的唯一方法是将逻辑编码到数据文件中(或者不编码,但实际上是将其写入您将发明的DSL中)。这样,C代码只需要找到一个正确的文件,读取它,然后运行它。文件名可以以
首字母
系统开头,以
终端
系统结尾。虽然不清楚您最后想要实现什么,但您可能希望查看。如果您试图自动计算是否存在通过C1、C2、…CN类型将a转换为B的路径,那么您应该阅读图形上的路径查找。您还可以研究“度量单位”转换的实现……似乎
MyObject
是非常可变的,对于
struct
,它不是一个很好的候选者。
case
语句似乎完全忽略了
开关
VARABLE
s
。这真的有效吗?如果你有不同的转换,并且这些转换必须手工编码,那么我没有得到“具有无限可能性的开关”语句,你仍然必须编写无限转换,那么重点在哪里呢?在
到系统结构b
到系统结构x
等中你有什么类型的代码?如果它们真的都不同,那么你的问题本质上是复杂的。我能想到的唯一方法是将逻辑编码到数据文件中(或者不编码,但实际上是将其写入您将发明的DSL中)。这样,C代码只需要找到一个正确的文件,读取它,然后运行它。文件名可以以
首字母
系统开头,以
终端
系统结尾。虽然不清楚您最后想要实现什么,但您可能希望查看。如果您试图自动计算是否存在将a转换为B的路径vi