我是编程新手,我想尝试创建一个返回自动增量id的函数,但是该代码无法正常工作,即使没有得到什么,我也肯定有一些缺失。 这里的代码是要创建一个每次都被调用的函数,它会创建一个自动增量id,就像在SQL(主键)上一样:
class Program
{
static void Main(string[] args)
{
string[] dataInsert = new string[10];
for(int i = 0; i < dataInsert.Length; i++)
{
dataInsert[i] = Convert.ToString(generateId());
}
for (int i = 0; i < dataInsert.Length; i++)
{
Console.WriteLine(dataInsert[i]);
}
Console.ReadKey();
}
static int generateId()
{
int id = 1;
return id += 1;
}
}
答案 0 :(得分:4)
更改
static int generateId()
{
int id = 1; //This resets the value to 1 every time you enter.
return id+= 1;
}
收件人:
private static int id = 1;
static int generateId()
{
return id++;
}
您的generateId将始终返回2,因为您将传递每次输入时都初始化为1的本地值。以我的示例为例,当应用运行时,Id将设置为1,然后递增。不过,它将始终从1开始。
添加对局部变量,字段变量和静态变量的说明。
像定义变量一样定义局部变量时,它仅存在于方法范围内,并且每次调用该方法时都会重新初始化。
您还可以定义只要存在对象实例就将存在的字段变量。例如:
public class AutoIncrment
{
private int id = 1;
public int GenerateId()
{
return id++;
}
}
您可以像这样使用它:
var idState = new AutoIncrement();
console.WriteLine(idState.GenerateId()); // Outputs 1
console.WriteLine(idState.GenerateId()); // Outputs 2
console.WriteLine(idState.GenerateId()); // Outputs 3
console.WriteLine(idState.GenerateId()); // Outputs 4 .. And so on
var idState2 = new AutoIncrement(); // Create a new instance and it starts over
console.WriteLine(idState2.GenerateId()); // Outputs 1
console.WriteLine(idState2.GenerateId()); // Outputs 2 .. And so on
// Go back to idState object and it will keep going from where you last left off
console.WriteLine(idState.GenerateId()); // Outputs 5
然后有一些静态变量,例如在顶部的答案中。它们作为类本身的一部分存在。由于该类在程序运行时始终存在,因此变量也存在于内存中。
答案 1 :(得分:3)
您可以制作一个static整数来记住先前返回的ID,然后使用Interlocked.Increment()
根据需要将其递增:
using System.Threading;
class Program
{
static int lastId = 0;
static int generateId()
{
return Interlocked.Increment(ref lastId);
}
// Remainder of Program unchanged
}
Interlocked.Increment
递增指定变量并将其存储为原子操作,并返回递增值。它保证了从不同线程调用generateId()
时不会返回重复的ID。
请注意文档中的以下remark:
此方法通过包装以下内容来处理溢出情况:if
location = Int32.MaxValue
,location + 1 = Int32.MinValue
。没有异常。
因此,您可能想向generateId()
添加逻辑以检查此内容并引发异常。
有关静态字段及其使用时间的更多信息,请参见:
What is the use of static variable in C#? When to use it? Why can't I declare the static variable inside method? 说明了何时以及如何使用静态字段。
C# Static variables - scope and persistence ,它说明了静态字段将在AppDomain
的生存期内持续存在(这可以合理地近似于应用程序会话的生存期)因此它的值在程序退出之前不会重置。
更新
在评论中,提出以下问题:如果我们不知道有多个线程(即假设这是一个单线程应用程序),为什么这里Interlocked.Increment
是必要的?
此时,应该始终假定应用是多线程的。如果有一种简单的线程安全模式替代方法,而无需花费大量额外成本(无论是开发成本还是运行时性能),都可以使用线程不安全模式,例如此处所示。由于OP自称为马德拉大学的学生,因此即使编写控制台应用程序,他们也应该开始学习线程安全模式,这样他们就不必取消学习线程不安全的知识技术。
答案 2 :(得分:0)
只需将您的int设为静态。
也可以在类空间中声明。不在函数中。
答案 3 :(得分:0)
您的代码始终以2
方法重新调整generateid()
:
static int id =1;
for(int i=0;i<dataInsert.Length;i++)
{
dataInsert[i] = Convert.ToString(generateId());
}
static int generateId()
{
return id+= 1;
}