C#中const的使用

Usage of const in C#

我想将下面的 cert 变量设为常量?当我这样做时,我得到一个错误,"The expression being assigned to cert must be a constant"。我在网上看到文章要求将其转换为 static readonly 而不是 const,并且还说要成为 const,其值应该在编译时已知。

我有两个问题

  1. 难道cert不可能是const变量吗,因为我不 要修改吗?
  2. 我尝试将 cert 变量设为只读,这也给了我 一个错误,"The modifier readonly is not valid for this item".

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

When I do that, I get an error, "The expression being assigned to cert must be a constant".

忽略你想要的,看看 c# 为 const 值提供的限制:const (C# Reference).

Constants can be numbers, Boolean values, strings, or a null reference.

我不知道还能告诉你什么,你根本不能使用实例化对象。

现在另一种创建稍微安全的 readonly 对象的方法是仅公开一个接口:

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

由于您没有包含此对象的任何用法,因此除了您不希望对象本身发生变化外,很难确定任何其他内容。

  1. 您不能使用const。你可以认为 const 不太像一个变量,而更像一个在编译时用值替换所有实例的宏。它只能与字符串和原语一起使用。

  2. 您只能对字段使用 readonly,不能对局部变量使用。也许这应该被允许,但事实并非如此。

不能将 const 用于实例化对象。 不过,一个不错的选择是 class 级别的静态只读字段。

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# 原始对象,例如字符串、整数、小数等。

不幸的是,目前变量不允许只读。然而,有人在谈论使之成为可能 https://www.infoq.com/news/2017/04/CSharp-Readonly-Locals