我们可以在同一类C#中调用方法吗

时间:2018-08-21 20:25:35

标签: c#

我有以下情况。我需要调用在同一类中实现的方法。但这会引发错误。我们该如何重写呢?

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);
    }
}

这种情况行得通吗?

4 个答案:

答案 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);
    }
}

通常公认的最佳实践是在构造函数内部初始化所有成员变量,而不是在声明它们时进行初始化,这有助于提高可读性和可维护性。