-2

I want to declare a variable in my class, that cannot be changed later like this:

obj myobj=new obj()
myobj.CONSTANT_VAR="Changed value" //ERROR!!

...but whose value can be accessed like:

Console.WriteLine(myobj.CONSTANT_VAR)

I tried the following:

public class obj{
    public int a, b;
    public const string CONSTANT_VAR;
    public obj(int x,int y){
        a=x;
        b=y;
        CONSTANT_VAR=1/(a*((""+a).Length)+3/(b*((""+b).Length)).ToString();
    }
    public int do(){
        return this.a+this.b-(CONSTANT_VAR).Length;
    }
}
class DriverClass(){
    static void Main(){
        obj myObj=new obj(2,3);
        myObj.a=34;
        myObj.b=35;
        myObj.CONSTANT_VAR="changed ur string lol"; //i want it to print error
      
        Console.WriteLine(CONSTANT_VAR); //no error
        Console.WriteLine(myObj.add());
    }
}

But i instead get the following error message:

constants must have a value assigned

But i dont want to assign it a value beforehand..... What do i do?

  • It would really help if you'd post code which is valid other than the problem you're facing - your class declarations are invalid to start with. It's also important to follow naming conventions, even when it's just sample code. – Jon Skeet Jun 14 '21 at 15:23
  • 3
    First of all, your code shouldn't compile, since you cannot use "()" in a class name. Then the message tells you already: _"constants must have a value assigned"_ , which you do not : `public const string CONSTANT_VAR;` - It has to be assigned right away. If you cannot do that, you cannot use a `const`. What you _can_ use instead is a `public readonly` field. That can be assigned in ctor. – Fildor Jun 14 '21 at 15:24
  • After someone changes `a` and/or `b` (like in your `Main` method) should `CONSTANT_VAR` reflect that change or stay as it was when the `obj` instance was constructed? –  Jun 14 '21 at 15:28
  • [C# Naming Conventions](https://www.c-sharpcorner.com/UploadFile/8a67c0/C-Sharp-coding-standards-and-naming-conventions/) and [C# Coding Standards and Naming Conventions](https://github.com/ktaranov/naming-convention/blob/master/C%23%20Coding%20Standards%20and%20Naming%20Conventions.md) and [C# Coding Conventions (C# Programming Guide)](https://learn.microsoft.com/dotnet/csharp/programming-guide/inside-a-program/coding-conventions) –  Jun 14 '21 at 15:29
  • sorry for the stupid mistake i made, as i have just moved from a language like python to c# – Psychopathic Azula Jun 14 '21 at 15:50

2 Answers2

7

You're looking for read-only fields or properties, not const which is for genuine global constants.

I'd recommend avoiding public fields entirely, and instead using properties - so in this case you'd want a get-only property. Following .NET naming conventions, you'd have something like:

public class Obj
{
    public int A { get; set; }
    public int B { get; set; }

    public string ConstantVar { get; }

    public Obj(int x, int y)
    {
        A = x;
        B = y;
        ConstantVar = /* complex expression */
    }

    public int Do() => A + B - ConstantVar.Length;
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 4
    OP: Mind that `Obj` is still a pretty poor choice for a class name. – Fildor Jun 14 '21 at 15:27
  • 4
    @Fildor: Absolutely. And `Do` is still a very poor choice for a method name, too. – Jon Skeet Jun 14 '21 at 15:28
  • Unrelated: Mind that in this examples `A` and `B` have setters, which means that you probably need to recalculate `ConstantVar` when they change, too. – Fildor Jun 14 '21 at 15:30
  • 1
    @Fildor: I was going by the fact that `a` and `b` in the original code can change, but it *sounds* like the OP wants `ConstantVar` to stay the same. Oh the joy of ambiguous questions :( – Jon Skeet Jun 14 '21 at 15:33
  • Fair enough, I think it should be good enough to give OP the basic idea. Just wanted to point it out explicitly. – Fildor Jun 14 '21 at 15:34
  • ok, it works, and this is such a compact way of writing the code........ i think i will accept it.... – Psychopathic Azula Jun 14 '21 at 15:55
2

You can use Readonly, it gives you option to set the value once and can not be changed later.

public class obj(){
    public int a, b;
    public readonly string CONSTANT_VAR;
    public obj(int x,int y){
        a=x;
        b=y;
        CONSTANT_VAR=1/(a*((""+a).Length)+3/(b*((""+b).Length)).ToString();
    }
    public int do(){
        return this.a+this.b-(CONSTANT_VAR).Length;
    }
}
class DriverClass(){
    static void Main(){
        obj myObj=new obj(2,3);
        myObj.a=34;
        myObj.b=35;
        myObj.CONSTANT_VAR="changed ur string lol"; //i want it to print error
      
        Console.WriteLine(CONSTANT_VAR); //no error
        Console.WriteLine(myObj.add());
    }
}
Amit Gupta
  • 252
  • 3
  • 8