0

How can I use a variable/const, declared in Main, inside another method? Without passing it like: static string my_method(string my_variable_to_pass) Just using static void my_method()

What I want is to call any other method into Main and it has to use the variable declared in Main.

I do not want to use public static class either because it does not seem the proper way. Is there another way?

Here is an example of what I want. This code does not work because "cats does not exist in the current contend" inside test_method(). But how could I make it work without adding too complicated code?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        string cats;

        cats = "1000 Cats";
        test_method();
        cats = "6 Cats";
        test_method();
    }

    static void test_method()
    {
        Console.Write(cats);
    }
}
16-bit
  • 19
  • 2
    Why not use private static then? – Timothy Ghanem Jun 08 '17 at 13:10
  • 2
    Pass `cats` as a parameter OR make it a class scoped field. – Igor Jun 08 '17 at 13:10
  • 1
    Make "cats" a static variable in your `Program` class – Alex Ferretti Jun 08 '17 at 13:10
  • You either pass the variable as a method parameter or you make the variable at the class level. Why don't you want to do either of these things? What are you actually trying to accomplish here? – David Jun 08 '17 at 13:11
  • 1
    `I do not want to use public static class either because it does not seem the proper way` - The "proper" way is to pass it as a parameter in this case. – Jamiec Jun 08 '17 at 13:12
  • As others have said, make the variable static belonging to the `Program` class. But the better answer is to learn OOP and use those design principles. You'll find everything is a lot easier when you don't fight against the paradigms that the language is designed around. – Matt Burland Jun 08 '17 at 13:13
  • 2
    So you ask if there's a way to do it after mentioning two ways to do it. Clearly you *already know* how to do it. – Servy Jun 08 '17 at 13:13

5 Answers5

3

What I want is to call any other method into Main and it has to use the variable declared in Main.

This is not possible without using a closure. However in your case it is much better to use a class-level field, like this:

class Program
{
    private static string cats;

    static void Main(string[] args)
    {
        cats = "1000 Cats";
        test_method();
        cats = "6 Cats";
        test_method();
    }

    static void test_method()
    {
        Console.Write(cats);
    }
}
Kapol
  • 6,383
  • 3
  • 21
  • 46
  • 2
    The only one who pointed that accessing local variable outside of method body is not possible) – Sergey Berezovskiy Jun 08 '17 at 13:16
  • 1
    @SergeyBerezovskiy That's simply false. Closures *specifically* allow exactly that. – Servy Jun 08 '17 at 13:19
  • @Servy Yes, that is true, although I think it's irrelevant for the sake of this question. – Kapol Jun 08 '17 at 13:21
  • @Servy closures *replace* local variables with fields of generated classes – Sergey Berezovskiy Jun 08 '17 at 13:21
  • 1
    @Kapol It's a poor solution to this problem, sure. That doesn't change the fact that the answer is false in its claims. – Servy Jun 08 '17 at 13:22
  • @SergeyBerezovskiy It doesn't matter how it's implemented by the compiler. The fact remains that a local can outlive its method body and be accessible from other methods. – Servy Jun 08 '17 at 13:23
  • @Servy As a C# developer I'm impressed I've never heard of closures before. Thanks for the info! – Camilo Terevinto Jun 08 '17 at 13:23
  • @Servy I modified my answer a bit, is this better now? :) – Kapol Jun 08 '17 at 13:24
  • So now your answer just makes entirely false claims, and later says that its own claims are false. That's confusing at best. If you know the claim is false, just don't make the false claim in the first place, instead of contradicting yourself. – Servy Jun 08 '17 at 13:25
  • @Servy it matters. Local cannot outlive its method body, but value of local can – Sergey Berezovskiy Jun 08 '17 at 13:27
  • 1
    @SergeyBerezovskiy No, that's *false*. Closures specifically allow you to access the *variable* of a local outside of the method body, not just the value. You can get the value, set the value, get a reference the the variable, etc. Closures close over *variables*, not values. – Servy Jun 08 '17 at 13:28
  • @Servy I second your claim about variable capturing. I have edited my post. Hopefully now it's OK for you. – Kapol Jun 08 '17 at 13:33
  • @Kapol Again, you're *still* saying that it's not possible, when it's possible. – Servy Jun 08 '17 at 13:34
  • @Servy Not anymore. – Kapol Jun 08 '17 at 13:39
  • @CamiloTerevinto This [example](https://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp) shows a nasty dark side of closures ;) there is also a nice reference to an article by John Skeet – Mong Zhu Jun 08 '17 at 14:09
1

I do not want to use public static class either because it does not seem the proper way. Is there another way?

You don't need a class, but at least a static field or property or move an instance along. It is either of those.

The scope of the variable is now only on the method level, you can't access it from anywhere else.

This will do:

class Program
{
    public static string Cats {get;private set;}

    static void Main(string[] args)
    {

Then call it:

var c = Program.Cats;

You could also encapsulate the property into a class and move that instance along.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
1

I think a number of the answers here are missing a valid point - the program has to be static, your functionality probably shouldnt be!

public class CatStuff
{
    private int cats;
    public CatStuff(int howManyCats)
    {
        this.cats = howManyCats;
    }

    public void TestMethod()
    {
        Console.WriteLine("{0} cats", this.cats);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var cats1 = new CatStuff(1000);
        cats1.TestMethod();

         var cats2 = new CatStuff(6);
        cats2.TestMethod();
    }
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
0

you can define variables at the class level, so they are scoped to the entire class:

class Program
{
    private static string cats;

    static void Main(string[] args)
    {    
        cats = "1000 Cats";
        test_method();
        cats = "6 Cats";
        test_method();
    }

    static void test_method()
    {
        Console.Write(cats);
    }
}

because you are using this in static methods, make sure your field is also static, as your static methods would not be allowed to access and instance field.

Jonesopolis
  • 25,034
  • 12
  • 68
  • 112
0

Declare static string cats; in Program class:

class Program
{
   static string cats;

  static void Main(string[] args)
  {
    cats = "1000 Cats";
    test_method();
    cats = "6 Cats";
    test_method();
  }

  static void test_method()
  {
    Console.Write(cats);
  }
}

That way cats can be accessed and used by any static method definied within Program class

pitersmx
  • 935
  • 8
  • 27