简体   繁体   English

const在C#中的用法

[英]Usage of const in C#

I would like to make the cert variable below to be a const? 我想将下面的cert变量设为const? When I do that, I get an error, "The expression being assigned to cert must be a constant". 当我这样做时,我得到一个错误,“分配给cert的表达式必须是一个常量”。 I have seen articles online asking to convert it to static readonly as opposed to const, and also saying that to be a const, the value should be known at compile time. 我在网上看到过一些文章要求将其转换为静态只读而不是const,并且还说要成为const,应在编译时知道其值。

I have two questions 我有两个问题

  1. Is it not possible for cert to be a const variable, since I do not want it to be modified? 因为我不希望修改cert,所以不可能将它作为const变量吗?
  2. I tried making the cert variable a readonly, and that too gives me an error, "The modifier readonly is not valid for this item". 我尝试将cert变量设置为只读,这也给我一个错误,“修改器只读对此项目无效”。

Program.cs 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 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;
        }
    }
}

const is compile time keyword that will replace all references to you're const variable with a hard coded value in the compiled code const是编译时关键字,它将用已编译代码中的硬编码值替换对您的const变量的所有引用

public class MyClass
{
    private const int MyNumber = 2;

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

When this gets compiled the resulting code looks like this 编译后,结果代码如下所示

public class MyClass
{


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

It will have been compiled to IL but you get the point. 它将被编译为IL,但是您明白了。

This means that you can only mark things as constant that are known at compile and are C# primitive objects, like string, int, decimal etc. 这意味着您只能将在编译时已知且属于C#基本对象的东西标记为常量,例如字符串,整数,十进制等。

readonly is currently not allowed for variables unfortunately. 不幸的是,变量当前不允许readonly。 However there is talk of making it possible https://www.infoq.com/news/2017/04/CSharp-Readonly-Locals 但是有谈论使其成为可能https://www.infoq.com/news/2017/04/CSharp-Readonly-Locals

  1. You can not use const . 您不能使用const You can think of const less like a variable, and more like a macro that replaces all instances with the value at compile time. 您可以认为const变量,而更像是在编译时用值替换所有实例的宏。 It can only be used with strings and primitives. 它只能与字符串和基元一起使用。

  2. You can only use readonly with fields, not with local variables. 您只能对字段使用readonly ,而不能对局部变量使用。 Maybe that should be allowed, but it is not. 也许应该允许,但事实并非如此。

I can see why you would want something like this, essentially the equivalent of const in JavaScript and TypeScript, or val in Kotlin. 我知道为什么您会想要这样的东西,基本上等于JavaScript和TypeScript中的const或Kotlin中的val

Alas, C# doesn't have this functionality, and unfortunately const doesn't work like that. C,C#没有此功能,但是不幸的是const不能那样工作。

You could do this: 您可以这样做:

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

When I do that, I get an error, "The expression being assigned to cert must be a constant". 当我这样做时,我得到一个错误,“分配给cert的表达式必须是一个常量”。

Ignoring what you want, and looking at the limitations of what c# provides for const values: const (C# Reference) . 忽略所需的内容,并查看c#为const值提供的限制: const(C#参考)

Constants can be numbers, Boolean values, strings, or a null reference. 常量可以是数字,布尔值,字符串或空引用。

I don't know what else to tell you, you simply can't use an instantiated object. 我不知道还能告诉您什么,您根本无法使用实例化的对象。

Now an alternate way to create a somewhat safe readonly object is to only expose an interface: 现在,创建一个稍微安全的只读对象的另一种方法是只公开一个接口:

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

Since you've not included any usage of this object, it's extremely hard to determine anything other than you don't want the object itself to change. 由于您尚未包含此对象的任何用法 ,因此除您不希望更改对象本身之外,很难确定其他任何内容。

You cannot use const with instantiated objects. 您不能将const与实例化对象一起使用。 A good alternative would be a static readonly field at class-level though. 一个好的替代方法是在类级别使用静态只读字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM