我有以下情况。我需要调用在同一类中实现的方法。但这会引发错误。我们该如何重写呢?
public class A
{
Random random = new Random(2);
string Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string randomString = GenerateString(5);
public string GenerateString(int size)
{
char[] chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = Alphabet[random.Next(Alphabet.Length)];
}
return new string(chars);
}
}
这种情况行得通吗?
答案 0 :(得分:5)
您需要了解constructors。 具体来说,在您的代码中,您需要一个初始化 randomString 的构造函数。此外,字母在执行过程中永远不会改变,因此成为 const 的最佳人选。
public class A {
const string Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public A()
{
random = new Random(2);
randomString = GenerateStrig(5);
}
public string GenerateString(int size)
{
char[] chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = Alphabet[random.Next(Alphabet.Length)];
}
return new string(chars);
}
string randomString;
Random random;
}
希望这会有所帮助。
答案 1 :(得分:5)
您不能在静态上下文中访问非静态方法GenerateString。 您可以像这样编写代码:
public class A
{
static Random _random = new Random(2);
const string Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string _randomString = GenerateString(5);
public static string GenerateString(int size)
{
char[] chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = Alphabet[random.Next(Alphabet.Length)];
}
return new string(chars);
}
}
答案 2 :(得分:3)
另一种可能性是将randomString
field 转换为只读的 property :
string randomString => GenerateString(5);
您要做的就是在>
之后添加=
;进一步重构:
public class A
{
//TODO: Random(2) for debug only; Random() for real life
readonly Random random = new Random(2);
// Alphabet is a constant isn't it?
const string Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// read-only property; initial value is GenerateString(5)
//TODO: You may want to capitalize the property - RandomString
string randomString => GenerateString(5);
public string GenerateString(int size)
{
// Validation
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size), "size must be non-negative");
// Linq is often compact and readable
return string.Concat(Enumerable
.Range(0, size)
.Select(i => Alphabet[random.Next(Alphabet.Length)]));
}
}
编辑:正如Progman在评论中所指出的,属性(因此GenerateString(5)
)将在每次访问时 执行,例如
A a = new A();
// call randomString 3 times
string test = string.Join(Environment.NewLine, Enumerable
.Range(0, 3).Select(i => a.randomString));
Console.Write(test);
将打印出三个不同值
RE5Z3
BSG80
R10ID
答案 3 :(得分:2)
更改必须包含的默认构造函数,并从中调用该构造函数。
public class A
{
Random random;
string Alphabet;
string randomString;
public A()
{
Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
random = new Random(2);
randomString = GenerateString(5);
}
public string GenerateString(int size)
{
char[] chars = new char[size];
for (int i = 0; i < size; i++)
{
chars[i] = Alphabet[random.Next(Alphabet.Length)];
}
return new string(chars);
}
}
通常公认的最佳实践是在构造函数内部初始化所有成员变量,而不是在声明它们时进行初始化,这有助于提高可读性和可维护性。