Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.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中重载的typedef等效项#_C#_Types_Overloading_Typedef - Fatal编程技术网

C# c中重载的typedef等效项#

C# c中重载的typedef等效项#,c#,types,overloading,typedef,C#,Types,Overloading,Typedef,我有一堆代码,其中有许多不同含义的整数(我更喜欢一个通用的解决方案,但有一个具体的例子:月日vs.月日vs.年等等)。我希望能够基于这些含义重载类构造函数 比如说 int a; // takes role A int b; // takes role B var A = new Foo(a); // should call one constructor var B = new Foo(b); // should call another constructor 现在很明显,这是行不通的

我有一堆代码,其中有许多不同含义的整数(我更喜欢一个通用的解决方案,但有一个具体的例子:月日vs.月日vs.年等等)。我希望能够基于这些含义重载类构造函数

比如说

int a; // takes role A
int b; // takes role B

var A = new Foo(a);  // should call one constructor
var B = new Foo(b);  // should call another constructor
现在很明显,这是行不通的,但是如果我可以定义一个类型(不仅仅是别名),它是一个
int
,除了名称之外,其他都是这样的:

typedef int TypeA;  // stealing the C syntax
typedef int TypeB;
 int dom = 5;
int doy = 100;

Foo b = Foo.NewFromDayoftheMonth(dom);

Foo c = Foo.NewFromDayoftheYear(doy);
我可以做我需要的重载,让类型系统跟踪什么是什么。特别是,这将允许我确保值不会混淆,例如,从函数返回的值作为一年不会用作一个月中的一天

在c#中,除了
结构
包装器之外,还有什么方法可以做到这一点吗



如果该解决方案也适用于浮点数和双精度浮点,那就太好了。

这可能有点不对劲,但您不能使用枚举来实现这一点吗?枚举基是int,但是类型化的,您可以根据传递的枚举的类型定义不同的构造函数。

如果只是针对构造函数,您不能使用如下内容:

typedef int TypeA;  // stealing the C syntax
typedef int TypeB;
 int dom = 5;
int doy = 100;

Foo b = Foo.NewFromDayoftheMonth(dom);

Foo c = Foo.NewFromDayoftheYear(doy);
其中每个方法都是静态的,并根据传入的参数创建一个新的Foo对象


对于我来说,这似乎是一个解决方案,没有太多其他解决方案。

没有直接的typedef等价物,但您可以执行以下操作:

using TypeA = int;
using TypeB = int;
但是,这只是给类型添加别名,而不是创建新的强类型。因此,在解析方法调用时,编译器仍将它们视为
int

更好的解决方案可能是创建简单的包装类,包装
int
,并提供隐式转换,例如:

struct TypeA
{
   public TypeA(int value)
   {
      this.realValue = value;
   }

   private int realValue;
   public static implicit operator int(TypeA value)
   {
     return this.realValue;
   }

   public static implicit operator TypeA(int value)
   {
     return new TypeA(value);
   }
}

但是,在大多数情况下,枚举更合适。

我还将围绕值创建一个结构:

public struct TypeA
{
  private int value;
  public TypeA(int value)
  {
    this.value = value;
  }

  public static explicit operator int(TypeA a)
  {
     return a.value;
  }

  public static explicit operator TypeA(int value)
  {
     return new TypeA(value);
  }
}
您还可以声明运算符来组合类型和方法,以围绕int值提供丰富的类型


年份类型可以提供一个
IsLeap
属性,一个月中的一天可以限制为1到31之间的值,并提供一个特殊的算法。

对于只允许较小范围(一年中的一个月)但在其他情况下(一年)的情况,这将起作用(+1)你需要开始破解,使c#允许没有定义的值-pIIRC c#限制如何设置枚举类型,使其仅具有定义的值。因此,给定“enum E{V=1}E;”E不经过一些修改就不能取值2。是的,我不知道你会怎么做。给你的最新编辑一个建议,一个扩展方法会有帮助吗?像是月还是年?您可以为枚举类型编写扩展方法@BCS:枚举值可以采用其基类型的任何其他值。因此,如果枚举是基于int的,则可以将任何int赋值给它,即使它只定义了例如1和2的名称。您只需在myEnumValue=(MyEnumType)42中强制转换为。这不是黑客攻击。这是我考虑过的一个选项,但我希望编译器能帮我检查。看我即将出版的编辑,这是一个结构,没有隐式转换是我最终要做的。它工作得很好。这会影响性能吗?或者C#编译器是否足够好,可以优化包装器?我缺少了一些与Haskell在C#中的新类型相当的东西(它们基本上就是您刚才所做的,但在编译期间(但在类型检查之后)会被删除)。我不知道是否会有很大的性能损失。恐怕你得试试看。