我们在JAVA中有Integer
类,但我在C#中找不到任何等效的类? c#有任何等价物吗?如果没有,我如何在c#中获得JAVA Integer
类行为?
我为什么需要这个?
这是因为我正在尝试将JAVA代码迁移到c#代码。如果存在等效方式,则代码迁移将更容易。要添加,我需要存储Integer
的引用,我认为我不能创建int
或Int32
的引用。
答案 0 :(得分:8)
C#具有统一的类型系统,因此可以将int
隐式地装入object
引用中。 Java中存在Integer
的唯一原因是它可以转换为对象引用并存储在引用中以便在其他容器类中使用。
由于C#可以在没有其他类型的情况下执行此操作,因此Integer
没有相应的类。
答案 1 :(得分:4)
对于任何类型的语言,代码迁移都不会开箱即用,无需任何手动更改。有一些诸如类Integer
之类的东西根本就不存在(C#为什么要反正,看看递归回答),所以你必须自己做一些工作。与您之后最接近的是Int32
或其别名int
。但是,您当然可以编写自己的包装类:
public class Integer
{
public int Value { get; set; }
public Integer() { }
public Integer( int value ) { Value = value; }
// Custom cast from "int":
public static implicit operator Integer( Int32 x ) { return new Integer( x ); }
// Custom cast to "int":
public static implicit operator Int32( Integer x ) { return x.Value; }
public override string ToString()
{
return string.Format( "Integer({0})", Value );
}
}
答案 2 :(得分:2)
C#的优点在于它具有统一的类型系统。一切都来自object
,甚至是原始类型。因此,所有关键字都只是对应类或结构的别名。 Java不使用统一类型系统,因此需要单独的Integer
类来包装int
原语。在C#int
中是Int32
结构的同义词。
你一直在寻找的东西就在你面前。直接在int
关键字(即int.whatever()
)上使用点表示法来访问Javian Integer
类的.NET版本的所有优点。
答案 3 :(得分:2)
我在控制台应用程序中使用Nullable类型进行了一些测试,看起来它们没有按照您的意愿行事。例如:
static void Main(string[] args)
{
int? x = 1;
Foo(ref x);
Console.WriteLine(x);//Writes 2
}
private static void Foo(ref int? y)
{
y += 1;
var l = new List<int?>();
l.Add(y);
l[0] += 1;//This does not affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 2
Foo2(l);
}
private static void Foo2(List<int?> l)
{
l[0] += 1;
Console.WriteLine(l[0]);//writes 4
}
但是如果您推送自己的泛型类来包装原始/值类型以便在您的应用程序中使用,您可以获得您期望的行为:
public class MyType<T>
{
public T Value { get; set; }
public MyType() : this(default(T))
{}
public MyType(T val)
{
Value = val;
}
public override string ToString()
{
return this.Value.ToString();
}
}
static void Main(string[] args)
{
var x = new MyType<int>(1);
Foo(x);
Console.WriteLine(x);//Writes 4
}
private static void Foo(MyType<int> y)
{
y.Value += 1;
var l = new List<MyType<int>>();
l.Add(y);
l[0].Value += 1;//This does affect the value of x devlared in Main
Console.WriteLine(l[0]);//Writes 3
Console.WriteLine(y);//writes 3
Foo2(l);
}
private static void Foo2(List<MyType<int>> l)
{
l[0].Value += 1;
Console.WriteLine(l[0]);//writes 4
}
答案 4 :(得分:1)
int,int?和System.Int32都是struct,因此都是值类型,不能与Java的Integer包装器类(引用类型)进行比较。
System.Object类虽然是引用类型,但由于装箱会创建不可变的对象,因此可能会引起问题。简而言之,您无法更改盒装值。
int a = 20;
Object objA = a; //Boxes a value type into a reference type, objA now points to boxed [20]
Object objB = objA; //Both objA & objB points to boxed [20]
objA = 40; //While objB points to boxed [20], objA points to a new boxed [40]
//Thus, it creates another ref type boxing a 40 value integer value type,
//Boxed values are immutable like string and above code does not alter value of previous boxed value [20]
Console.WriteLine($"objA = {objA}, objB={objB}");
//Output: objA = 40, objB=20
与Java的Integer完全对应的是一个自定义的通用包装器类。
int a = 20;
Wrapper<int> wrapA = new Wrapper<int>(a);
Wrapper<int> wrapB = wrapA; //both wrapA and wrapB are pointing to [20]
wrapA.Value = 40; //Changing actual value which both wrapA and wrapB are pointing to
Console.WriteLine($"wrapA = {wrapA}, wrapB={wrapB}");
//Output: wrapA = 40, wrapB=40
Console.ReadKey();
包装类的实现如下:
public class Wrapper<T> where T : struct
{
public static implicit operator T(Wrapper<T> w)
{
return w.Value;
}
public Wrapper(T t)
{
_t = t;
}
public T Value
{
get
{
return _t;
}
set
{
_t = value;
}
}
public override string ToString()
{
return _t.ToString();
}
private T _t;
}
答案 5 :(得分:0)
正如其他答案中所指出的,C# 具有统一的类型系统,因此所有内容都源自 object
。如果您需要处理 null
值,则使用 int?
指定整数对象可以是 null
。
答案 6 :(得分:-2)
c#有一个整数类型,名为int link is here