1

我想将下面的 cert 变量设为 const?当我这样做时,我收到一个错误,“分配给 cert 的表达式必须是一个常量”。我在网上看到文章要求将其转换为静态只读而不是 const,并且还说要成为 const,应该在编译时知道该值。

我有两个问题

  1. cert 不可能是一个 const 变量,因为我不希望它被修改吗?
  2. 我尝试将 cert 变量设置为只读,这也给了我一个错误,“只读修饰符对此项目无效”。

程序.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");
        }
    }
}

我的工厂.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;
        }
    }
}
4

4 回答 4

3

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# 原始对象的东西标记为常量,例如字符串、整数、小数等。

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

于 2018-10-06T00:28:03.827 回答
1
  1. 你不能使用const. 您可以const不将其视为变量,而将其视为在编译时将所有实例替换为值的宏。它只能与字符串和原语一起使用。

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

于 2018-10-06T00:19:38.943 回答
0

当我这样做时,我收到一个错误,“分配给 cert 的表达式必须是一个常量”。

忽略您想要的,并查看 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;
        }
    }
}

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

于 2018-10-06T00:19:19.343 回答
0

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

于 2018-10-06T00:25:13.663 回答