-3

First of all, I'm NOT really familiar with C#, but I am with C++. I didn't find any info about this. Through what mechanism is a C# property is being set when it only have a get implemented and the set is hidden. It's a read-only property that is being set continuously, inside a loop.

My hunch is that the get returns a reference which C# uses to set the value in this case. Is that correct?

(I've come across a code which I'm trying to understand)

For example:

public Series<double> Avg
{
    get { return Values[1]; }
}

public Series<double> Default
{
    get { return Values[0]; }
}

(Series is just an array of doubles, but accessing them from the end of the array, by index)

The code in RSI does write the items of the array:

Default[0]  = value0;
Avg[0]      = constant1 * value0 + constant2 * Avg[1];

So what is happening up there? Just to understand, it is something like the below C++ code?

double& Avg(int index)
{
    return Values[index+1];
}

Certainly, in C++ you would use Avg(1) instead of Avg[1] since it is a function, I'm just curious what the logic actually does in @RSI.cs. Is the get in this case is like a reference so it can also write values via the get or is the set is auto-implemented so writing and reading the above properties is accessing a completely different index or even variable?

Are the above C# samples even a valid C# code?

Thomas
  • 816
  • 5
  • 16
  • 4
    that means it's read-only property – Ehsan Sajjad Mar 04 '18 at 12:47
  • next logical question, how can the above code write a read-only property? – Thomas Mar 04 '18 at 12:52
  • There is no `set`. The `get` returns a `Series` and the calling code proceeds to set the first value of this series. Nowhere are the values of `Avg` and `Default` set in the code you posted. The c++ code you posted is completely different and unrelated. Note I don't know exactly what `Series` is but apparently it has an indexer operator. – Rotem Mar 04 '18 at 12:52
  • See the (links in) the answers of [this](https://stackoverflow.com/questions/2719699/when-should-use-readonly-and-get-only-properties) question. It lists some reasons for doing this. – Peter Bons Mar 04 '18 at 12:57
  • 2
    @Thomas: a property that only has a getter will normally refer to a private field which will be written to internally. In your case this is represented by the array elements Values[1] and Values[0]. – oliver Mar 04 '18 at 12:57
  • 1
    oliver, thanks. you are the one who understood my question :) – Thomas Mar 04 '18 at 12:59
  • 1
    Possible duplicate of [How to implement a read only property](https://stackoverflow.com/questions/3917796/how-to-implement-a-read-only-property) – paparazzo Mar 04 '18 at 13:24
  • where exactly that post explains what happens while setting a read-only property? how can it be set without a set, how can it be set through a get, how is it happening under the hood is what this thread is all about. – Thomas Mar 04 '18 at 16:01

4 Answers4

3

That means you can only read the value of the property but not write it from the outside.

Take a file class for example. It would have a property FileSize that you could read from the outside. It would make no sense to have a Setter since setting the file size should not be possible (you have to modify the content of the file in order for the file size to change).

You would then implement a read only property in the form of the following:

public long FileSize { get { return Content.Length; } }

You can compare a C# property to a set of C++ methods. A get would be a getProperty() method in your C++ class and a set would be a setProperty(value). A C# property is actually not very different from having a field and two methods. The whole get and set is just a nice way to let the compiler generate this for you.

Sylence
  • 2,975
  • 2
  • 24
  • 31
  • You do not write to the property but rather to the object the property has returned, i.e. an object of type Series. – oliver Mar 04 '18 at 12:59
  • Pretend it's two separate statements: `Series a = Avg; a[0] = ...;` – Rotem Mar 04 '18 at 13:00
  • thank you oliver. This means, my C++ example is accurate, right? – Thomas Mar 04 '18 at 13:00
  • I feel like the answer from Rotem and oliver is different. Am I writing the original array or a "pretend" one? (newly defined that will be left when the code gets outside of the scope) The indicator wouldn't be able to build up it's values that way. The sample code is inside a for loop. oliver's answer makes more sense to me right now. – Thomas Mar 04 '18 at 13:02
  • @Thomas: not really, double& is a reference to a double value whereas Series seems to be something like an encapsulated double array. Replace double& by double* and it's a little more similar. But actually it is difficult to compare c# and c++ because in C++ you have to dereference pointers explicitely whereas in c# it's done implicitely so to say. – oliver Mar 04 '18 at 13:04
  • @Thomas I think there's some confusion about the types. You didn't show the exact type of `Values`, but seems it's something like an array of arrays. `Avg` returns the first array and `Default` returns the second array. Think of the `Avg` property as c++ `std::vector& GetAvg() { return Values[0]; }`. And then the calling code doing something like `GetAvg()[0] = ...;`. – Rotem Mar 04 '18 at 13:05
  • oh yeah Rotem, we're on the same page now! My example was confusing, yours is the same as mine because Values[0] is accessing it by index, via an internal variable. But now, I understand what is happening, thank you for your effort in trying to understanding me. – Thomas Mar 04 '18 at 13:11
  • I always meant it this way, but I see now how my example didn't make sense from an external point of view (for someone who is not familiar with how the Series "template" works. It's called differently in C#, I know :) But can't recall it right now :) – Thomas Mar 04 '18 at 13:12
  • the exact type of Values is public Series[] Values { get; } – Thomas Mar 04 '18 at 13:13
1

This means that this is a property that you want it to be read from outside the object without modifying it, for example you can do this:

public class MyObject
{
    private string _currentState;//This will be changed only from inside class
    public string MyCurrentState
    {
       get
       {
         return _currentState;
       }
    }
}
Ali Ezzat Odeh
  • 2,093
  • 1
  • 17
  • 17
-1

Since you are more familiar with c++, let me try to translate it somehow. Forgive me any detail errors because it's been some time since I used C++ on a regular basis.

template<class T> class Series
{
    // some template class definition

    // the index operator in c++
    T& operator [](int idx) 
    {
        return somePrivateTArray[idx];
    }
}

class UserOfSeries
{
    Series<double> Values[]; // = ... somewhere

public:
    Series<double>& Avg()
    {
        return Values[1];
    }

    Series<double>& Default()
    {
        return Values[0];
    }
}

When you use it, you will probably write

UserOfSeries* aUserOfSeries = getUserOfSeriesFromTheSystem();
Series<double>& theAvg = aUserOfSeries->Avg();
theAvg[4] = 12000.000;
oliver
  • 2,771
  • 15
  • 32
  • 1
    Amazing, the accepted answer to a c# question has only c++ code. You didn't even explain what's happening in the c# code – Camilo Terevinto Mar 04 '18 at 13:28
  • @Camilo Terevinto: what's the problem? My aim is to help the OP. He is coming from C++, I will explain him in his familiar language. He can refer to the other answers as to the c# part. – oliver Mar 04 '18 at 13:30
  • @Camilo Sorry about that. When Avg[0] is set, it is writing Values[1] via a reference. – Thomas Mar 04 '18 at 13:31
  • 1
    The problem is that the OP is learning c#, not c++. This doesn't explain why you can have readonly properties in c# nor why they are useful nor how they work – Camilo Terevinto Mar 04 '18 at 13:32
  • My question was about what happens when writing. Visibility is a different topic. Actually it is not even a read-only property (in the English sense) since you can write it inside the same class. – Thomas Mar 04 '18 at 13:33
-2

You can set a property without a set. It only means you cannot access it from outside the class (visibility). Inside the class, the get acts as a reference as I write the values, so setting happens throughout the get if you will.

It means that my original C++ example is correct but a more accurate one is (by Rotem) std::vector& GetAvg() { return Values[0]; } so writing happens like this: GetAvg()[0] = ...;

Thank you Oliver and Rotem for your effort in trying understanding my answer. I feel like this is a good and supporting community. The ones who misunderstood my question as a visibility question were downvoting this though :-)

Thomas
  • 816
  • 5
  • 16
  • 1
    A property without a set is a read-only property. You can only assign the value in the constructor. If you wanted to be able to modify it afterwards, you'd need to have a `private set;`. It's not about who can assign it, it's about making it readonly – Camilo Terevinto Mar 04 '18 at 13:31
  • As I already said, you are NOT changing the (readonly) property, but the OBJECT that has been returned by the property. This could of course mean that you have effectively changed the inner state of the object the property getter of which you have called. – oliver Mar 04 '18 at 13:33