Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.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#_Replace_Compilation_C Preprocessor_Primitive Types - Fatal编程技术网

C# 在编译到不同的目标时,如何临时用另一个基元类型替换一个基元类型?

C# 在编译到不同的目标时,如何临时用另一个基元类型替换一个基元类型?,c#,replace,compilation,c-preprocessor,primitive-types,C#,Replace,Compilation,C Preprocessor,Primitive Types,如何轻松/快速地替换双精度浮点(例如),以便使用这两种特殊的原语类型选择编译到两个不同的目标 讨论: 我有大量的c#代码正在开发中,我需要编译它们,根据目标程序集的用例,交替使用浮点、双精度或小数 使用类似于“classmynumber:Double”的东西,只需要更改一行代码,因为Double是密封的,显然在C中没有定义。 在代码中添加#if#else语句也不是一个选项,使用这些特定基元类型的支持数学运算符/相关代码太多了 我不知道如何做这项看似简单的任务,谢谢 编辑:关于Kyles回复中提到

如何轻松/快速地替换双精度浮点(例如),以便使用这两种特殊的原语类型选择编译到两个不同的目标

讨论: 我有大量的c#代码正在开发中,我需要编译它们,根据目标程序集的用例,交替使用浮点、双精度或小数

使用类似于“classmynumber:Double”的东西,只需要更改一行代码,因为Double是密封的,显然在C中没有定义。 在代码中添加#if#else语句也不是一个选项,使用这些特定基元类型的支持数学运算符/相关代码太多了

我不知道如何做这项看似简单的任务,谢谢


编辑:关于Kyles回复中提到的拳击,只是一个简短的评论:不幸的是,我需要避免拳击,主要是因为当需要最大速度时选择浮点数,当最大精度是优先级时选择小数(并且接受20倍以上的性能命中是可以接受的)。拳击可能会排除小数作为一个有效的选择,并在某种程度上违背这个目的


编辑2:作为参考,那些建议将泛型作为这个问题的可能答案的人注意到,有许多问题不考虑泛型(至少对于我们的需求而言)。有关概述和更多参考资料,请参见

最坏情况下,我认为您可以使用拳击和类似的东西:

#if USE_FLOAT
public float OutputValue(object input)
{
    return (float)input;
}
#endif

#if USE_DOUBLE
public double OutputValue(object input)
{
    return (double)input;
}
#endif
#if USE_FLOAT
using Numeric = System.Single;
#endif

#if USE_DOUBLE
using Numeric = System.Double;
#endif

#if USE_DECIMAL
using Numeric = System.Decimal;
#endif

public class SomeClass
{
    public Numeric MyValue{get;set;}
}

调用
OutputValue(1.5)来让它为您转换。

一种方法是在您需要的基本类型周围有一个泛型。然后在一个单独的.cs文件中声明一个继承该泛型的特定实例的类,并为所需的每个基类型创建该类的三个副本。然后根据构建配置更改.csproj以包含适当的.cs文件

请注意,我还没有真正尝试过这一点,因此可能有一些纠结需要解决。

您可以这样做:

public struct NumberContainer<T> 
{
    T _number;

    // accessor, and possibly: operators, cast methods, etc.
}
public struct NumberContainer
{
T_数;
//访问器,可能还有:运算符、强制转换方法等。
}
然后:

#if USE_FLOAT
public struct MyNumber : NumberContainer<float>
#else
public struct MyNumber : NumberContainer<double>
#endif
{
}
#如果使用浮点数
公共结构MyNumber:NumberContainer
#否则
公共结构MyNumber:NumberContainer
#恩迪夫
{
}

最好的方法是使用如上所述的#if。然而,一个有趣的想法是这样的:

#if USE_FLOAT
public float OutputValue(object input)
{
    return (float)input;
}
#endif

#if USE_DOUBLE
public double OutputValue(object input)
{
    return (double)input;
}
#endif
#if USE_FLOAT
using Numeric = System.Single;
#endif

#if USE_DOUBLE
using Numeric = System.Double;
#endif

#if USE_DECIMAL
using Numeric = System.Decimal;
#endif

public class SomeClass
{
    public Numeric MyValue{get;set;}
}
编辑:

我仍然非常喜欢这个解决方案,它允许您做一些其他非常酷的事情,例如:

Numeric.Parse();
Numeric.TryParse();

这将适用于所有三种类型

这是很困难的,因为基本类型不会推动类似IArithmetic的东西。这是一个很好的例子。不幸的是,这是一个错误

有一些变通方法,使用一个。如果所做的计算不太繁重,那么这非常非常有效

然而,它很笨重。这是一个泛型不如C++模板灵活的地方。
另一种方法是使用类似的方法生成一个可用于任何类型的模板,并为每个类型编译单独的模板。

Uuuh。。。我不喜欢这个解决方案,它将您通常期望的值类型转换为引用类型。你没有将NumberContains设置为一个结构是有原因的吗?另外,继承链是不必要的,因为你可以使用:#如果使用_floatusing MyNumber=NumberContains#endif,然后使NumberContainer非抽象对不起,是的,一个结构会更好。。。我考虑的是主要结构而不是细节。编辑过。是的,但你必须在每个文件中使用#if/这是一件痛苦的事。是的,我正在想办法绕过#if在每个文件中,但我没有太多运气+1个好问题,这里提出了很多不同的解决方案,所有这些都非常相似,但无论如何,这是一个值得思考的有趣的问题。我现在可能会在将来使用它。不幸的是,我需要避免拳击,主要是因为当需要最大速度时选择浮点数,当最大精度是优先考虑的时候选择小数,并且接受20倍以上的性能打击是可以接受的。装箱可能会排除小数作为有效选择的可能性。不过谢谢你的建议-我将在主要问题中解决这个问题。我开始考虑一个泛型解决方案,然后我看到了这个。这么简单。是的:唯一真正的缺点是你必须把这个结构放在你所有的文件中;但这一点显然被以下事实所压倒:您可以像对待原始类型名一样对待以这种方式声明的变量+1在考虑了一段时间的文件问题后,我能想到的最好办法是将整个事情围绕在一个区域内,将其最小化,然后忘掉它。。。没什么可以做的,有点不好意思,不可能把这个结构放在一个单独的文件中,然后导入它或者其他什么?另外,应该在后两个选项中使用
#elif
或其他什么?