【问题标题】:Usage of const in C#C#中const的使用
【发布时间】:2018-10-06 00:11:21
【问题描述】:

我想将下面的 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");
        }
    }
}

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

【问题讨论】:

    标签: c# oop constants readonly-attribute


    【解决方案1】:

    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

    【讨论】:

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

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

      【讨论】:

      • 我通过说“将const 视为文字的符号别名”来解释它。如果不能使用文字,就不能使用 const
      【解决方案3】:

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

      【讨论】:

      • 就像你的意思, public static class Program { static MyFactory myFactory = new MyFactory();静态 KeyGen secretsProvider = myFactory.GenerateKeyProvider();静态只读 int cert = secretsProvider.GetKey("arg");静态无效主(字符串[] args){程序开始(); } 私有静态无效 programStart() { Console.WriteLine(cert); Console.ReadLine(); } } 那行得通。
      【解决方案4】:

      当我这样做时,我得到一个错误,“分配给 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;
              }
          }
      }
      

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

      【讨论】:

        猜你喜欢
        • 2013-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        相关资源
        最近更新 更多