Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c#: keep ref parameter from constructor in class

Basically i would like to be able to have a reference to a variable inside a instance of a class, but i'd like the reference to become a class variable so I dont need to send it around inside of the class as parameter

code:

int num = 0;
myClass(num);
print num; // output is 0 but i'd like it to be 10 :)
class myClass
{
    private int classNumber;
    myClass(ref int number)
    {
        print number; //output is 0

        // id like this to be a reference to the refenrence
        classNumber = number;

        DoSomething();
    }
    public void DoSomething()
    {
        ClassNumber = 10;
    }
}

why i'm asking this is because i'm working with winforms and having a main form sending an instance of a class to a new form that should edit the class and send it back.. right now i use Form.ShowDialog() to avoid the user to use the main form while editing in the new form and after that grabbing the data from the new forms

editForm edtfrm = new editForm(ref instanceOfClass);
edtfrm.showDialog();
//grab the instance back
instanceOfClass = edtfrm.editedClass;

How can i solve this? i don't like this solution

like image 395
Tistatos Avatar asked Mar 10 '11 14:03

Tistatos


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.


3 Answers

i would like to be able to have a reference to a variable inside a instance of a class, but i'd like the reference to become a class variable so I dont need to send it around inside of the class as parameter

You will have to live with disappointment then. The CLR type system explicitly forbids storage of references to variables as members of classes. The CLR permits references to variables to be

  • passed to methods as arguments corresponding to formal parameters or 'this'
  • stored as locals
  • returned as method return values

but does not permit storage in arrays, fields, and so on. Basically, anything that goes "on the heap" can't hold onto a ref.

C# exposes the first feature: refs to variables as method parameters. It does not expose the other two features (though I have written an experimental version of C# which does, and it works quite nicely.)

Note that C# does not allow you to use refs in contexts which would require heap storage of the ref -- like a ref parameter being a closed-over outer variable of a lambda, for example. There are a few rare cases in which the compiler does allow what looks like long-term storage of the ref, and uses copy-in-copy-out semantics to emulate the ref, but probably best to not even go there.

Why does the CLR have this restriction? The right way to think about it is that there are two kinds of storage: long term and short term, usually called "heap" and "stack". But the shape of the data structure is irrelevant; what is relevant is the length of the lifetime. A variable has a storage location; that's what a variable is. If you could keep a ref to a variable allocated from the short-term storage in a long-term storage then the long-term storage keeps a ref to something that is of shorter lifetime, and therefore might crash and die when it accesses the variable after its death.

Obviously there are many ways to solve this problem. For example, the CLR team could have chosen to make it illegal to take a ref to short-term storage, and allow storage of refs in long-term storage. But that then means that you can't take refs to local variables or parameters, which you would like to put in short-term storage because their lives are so short.

The way the CLR team actually chose was to disallow long-term storage of any ref. Like any design decision, it was the result of many tradeoffs against competing goals.

like image 122
Eric Lippert Avatar answered Oct 25 '22 18:10

Eric Lippert


It's not really a good idea what you are trying to do, I would expose the modified object as a property of the class like below:

public class ClassContructorReference
{
    static void Main(string[] args)
    {
        object var = new object();
        MyClass myClass = new MyClass(var);
        StringBuilder mySb = myClass.Instance as StringBuilder;
        Console.WriteLine(mySb.ToString());
    }
}

public class MyClass
{
    public object Instance {get;set;}

    public MyClass(object var)
    {
        this.Instance = var;
        DoSomething();
    }

    private void DoSomething()
    {
        this.Instance = new StringBuilder("Hello");
    }
}
like image 21
Lee Dale Avatar answered Oct 25 '22 20:10

Lee Dale


Ofcourse your test code will not work as it is a primitive type.but your 2nd code will work as it is a reference type.(even 'ref' is not needed)No need to assign the instance back.

public class Second
{
    public First f;

    public Second(First f)
    {
        this.f= f;
    }

    public void change()
    {
        this.f.Name = "PUli";
    }
}
public class First
{
    private string _name;

    public First()
    {
        Name = "SUli";
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}
class Program
{
    static void Main(String[] args)
    {
        First f = new First();
        Second sec = new Second(f);
        Console.WriteLine(f.Name);
        sec.change();
        Console.WriteLine(f.Name);
    }
}

Output:-

SUli

PUli

like image 29
Tamilmaran Avatar answered Oct 25 '22 18:10

Tamilmaran