Использование const в C # - PullRequest
       52

Использование const в C #

0 голосов
/ 06 октября 2018

Я хотел бы сделать приведенную ниже переменную cert константой?Когда я это делаю, я получаю ошибку: «Выражение, назначаемое сертификату, должно быть константой».В Интернете я видел статьи, в которых просили преобразовать их в статические readonly, а не в const, а также говорили, что, чтобы быть const, значение должно быть известно во время компиляции.

У меня есть два вопроса

  1. Разве невозможно, чтобы сертификат был константной переменной, так как я не хочу, чтобы он был изменен?
  2. Я попытался сделать переменную cert доступной только для чтения, и это также выдает мне ошибку «Модификатор только для чтения недопустим для этого элемента».

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IAMAGoodDeveloper
{
    public static class Program
    {
        static void Main(string[] args)
        {
            programStart();
        }

        private static void programStart()
        {
            var myFactory = new MyFactory();
            var secretsProvider = myFactory.GenerateKeyProvider();
            const int cert = secretsProvider.GetKey("arg");
        }
    }
}

MyFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IAMAGoodDeveloper
{
    public class MyFactory
    {
        public KeyGen GenerateKeyProvider()
        {
            return new KeyGen();
        }
    }

    public class KeyGen
    {
        public int GetKey(string arg)
        {
            return 1;
        }
    }
}

Ответы [ 5 ]

0 голосов
/ 06 октября 2018

const - ключевое слово времени компиляции, которое заменит все ссылки на вашу переменную const жестко закодированным значением в скомпилированном коде

public class MyClass
{
    private const int MyNumber = 2;

    public void MyMethod()
    {
        Console.WriteLine(MyNumber);
    }
}

Когда это скомпилируется, результирующий код выглядит следующим образом

public class MyClass
{


    public void MyMethod()
    {
        Console.WriteLine(2);
    }
}

Он будет скомпилирован в IL, но вы получите точку.

Это означает, что вы можете помечать вещи как константы, которые известны при компиляции и являются примитивными объектами C #, например string, int, decimal и т. д.

readonly в настоящее время, к сожалению, не разрешен для переменных.Однако есть разговоры о том, чтобы сделать это возможным https://www.infoq.com/news/2017/04/CSharp-Readonly-Locals

0 голосов
/ 06 октября 2018

Вы не можете использовать const с созданными объектами.Хорошей альтернативой было бы статическое поле только для чтения на уровне класса.

0 голосов
/ 06 октября 2018
  1. Нельзя использовать const.Вы можете думать о const меньше как о переменной и больше как о макросе, который заменяет все экземпляры значением во время компиляции.Он может использоваться только со строками и примитивами.

  2. Вы можете использовать readonly только с полями, но не с локальными переменными.Может быть, это должно быть разрешено, но это не так.

0 голосов
/ 06 октября 2018

Я понимаю, почему вы хотите что-то подобное, по сути, эквивалентное const в JavaScript и TypeScript или val в Kotlin.

Увы, в C # такой функции нет, и, к сожалению, const так не работает.

Вы можете сделать это:

namespace IAMAGoodDeveloper
{
    public static class Program
    {
        private static readonly int cert;

        static void Main(string[] args)
        {
            var myFactory = new MyFactory();
            var secretsProvider = myFactory.GenerateKeyProvider();
            cert = secretsProvider.GetKey("arg");
        }
    }
}
0 голосов
/ 06 октября 2018

Когда я это делаю, я получаю сообщение об ошибке «Выражение, назначаемое для сертификата, должно быть константой».

Игнорирование того, что вы хотите, и рассмотрение ограничений того, чтоc # обеспечивает const значения: const (C # Reference) .

Константами могут быть числа, логические значения, строки или нулевая ссылка.

Я не знаю, что еще вам сказать, вы просто не можете использовать экземпляр объекта.

Теперь альтернативный способ создания несколько безопасного только для чтения объект должен представлять только интерфейс:

public class MyFactory
{
    public IKeyGen GenerateKeyProvider()
    {
        return new KeyGen();
    }

    public interface IKeyGen 
    {
      int GetKey(string arg);
    }

    private class KeyGen : IKeyGen
    {
        public int GetKey(string arg)
        {
            return 1;
        }
    }
}

Поскольку вы не включили использование этого объекта, крайне сложно определить что-либо, кроме того, что вы не хотите, чтобы этот объектсам поменять.

...