4

Recently I have been working with C# and I ran into this curious problem. I tried to set a value to the read-only property of the excel chart class, before I read the documentation and discovered that the property is read-only.

var charts= worksheet.ChartObjects() as xcel.ChartObjects;
var chartObj = charts.Add(60,10,200,400) as xcel.ChartObject;
var chart = chartObj.Chart;
chart.Name = "GicsSectorIndustry";   <--

I get this error:

Insufficient memory to continue the execution of the program

When I remove that line, the code works perfectly, so it led me to wonder what happens behind the scenes when I try to set a value for the read-only property that causes it to "run out of memory".

Twenty
  • 5,234
  • 4
  • 32
  • 67
Adas
  • 404
  • 2
  • 19
  • 1
    I am pretty sure that the property setter of `chart.Name` got changed. You should take a look at the source code if it is publicly available or try ILSpy. – Twenty Dec 19 '19 at 16:39
  • Nothing happens, that's the point of read only. Think about it, if you had a property you didn't want to change the value of, what would you do? It's pretty much the same logic for the attribute. – Train Dec 19 '19 at 16:43
  • 2
    @Train then I am confused why it would throw `Insufficient memory error`, instead of `cannot set value to read-only property` – Adas Dec 19 '19 at 16:44
  • @Adas why do you think that it is read-only? `Insufficient memory to continue the execution of the program` sounds like a runtime error. But the compiler shouldn't even let you compile since it is readonly. You should have an error like this `A readonly field cannot be assigned to (except in a constructor or a variable initializer)`. Therefor why do you think it is readonly? – Twenty Dec 19 '19 at 16:48
  • 2
    Also here is how to change the name https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.tools.excel.chart.name?view=vsto-2017 `Excel.ChartObject chartObjectParent = chart1.Parent as Excel.ChartObject; chartObjectParent.Name = "new name"` – Train Dec 19 '19 at 16:50
  • @Twenty according to this site, its read-only https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.tools.excel.chart.name?view=vsto-2017 – Adas Dec 19 '19 at 16:51
  • @Twenty look at my link, the definition is `public string Name { get; }` – Train Dec 19 '19 at 16:52
  • @Train I did, thats where I read it was read-only `Although the Name property is read-only, you can modify a portion of the name by using the Name property`, I understand that it can be changed – Adas Dec 19 '19 at 16:53
  • 2
    Well so it is not really readonly it is essentially `public string Name { get; private set; }` according to this [SO Post](https://stackoverflow.com/questions/2719699/when-should-use-readonly-and-get-only-properties). Anyhow the compiler should still throw.... – Twenty Dec 19 '19 at 16:55
  • @Twenty thank you for this, i understand it more now – Adas Dec 19 '19 at 16:57
  • @Adas really you should at least hit `CTRL` + `LMB` on the `Name` property in order to see the signature of the property and why your compiler is not complaining. – Twenty Dec 19 '19 at 16:58
  • @Twenty i did that, and now it seems that its not a get only property, it had `string Name { get; set; }` – Adas Dec 19 '19 at 17:04
  • @Adas the reason for this is because if it's an embedded chart/nested it's read only, otherwise it's not. Is that chart in another chart? – Trevor Dec 19 '19 at 17:07
  • What's the namespace of the class you are using? – JuanR Dec 19 '19 at 17:25
  • @Çöđěxěŕ nope, its just one chart – Adas Dec 19 '19 at 18:18
  • @JuanR the namespace is Microsoft.Office.Interop.Excel – Adas Dec 19 '19 at 18:18

2 Answers2

0

If it was read-only, you could not compile that code. This means it's not read-only but the documentation says to treat it as read-only.


Rephrased question: What happens when you try to assign to an assignable property that the documentation says to treat as read-only?

Short answer: Does it matter?

Long answer: Without the source, it's very hard to tell. You could use ILSpy to debug it but the short answer still applies.

IOrlandoni
  • 1,790
  • 13
  • 30
  • It's unlikely that you would get much of an answer with ILSpy (or any other decompiler). The Office interop libraries are just a wrapper for the C interface, so without delving into the C code it would be difficult to tell exactly what is happening under the hood. – Ron Beyer Dec 19 '19 at 18:49
0

It seems you are reading the wrong documentation.

I had inquired as to what namespace the class you were using came from. According to the documentation for the Interop assembly, the signature is:

public:
property System::String ^ Name { System::String ^ get(); void set(System::String ^ value); };

As you can see, there is a setter.

You can read more about it here.

There exists another version (a wrapper, I imagine) from Tools for Office. The signature for that one does not provide a setter:

public string Name { get; }

More information on that one can be found here.

Interop assemblies bridge between managed and unmanaged code so my educated guess is that the second version (wrapper) probably exists to manage issues like the one you are experiencing, or it could be another Interop implementation all together.

As others have stated, if no setter was provided, your code just wouldn't compile but in this case it does. It's just something goes wrong under the covers.

UPDATE:

I found the following concerning the difference between the two implementations:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/86a62151-fbf0-4584-a68c-83060fb95c3d/officeinteropexcel?forum=vsto

JuanR
  • 7,405
  • 1
  • 19
  • 30