Change virtual property - c#

I'm currently working on some existing C# code and i simply want to set a property to null when a given code doesn't exist in the system.
The code i currently have looks like this:
if (!CodeExists(SomeClass.Code))
{
SomeClass.Code = null;
}
So assume that SomeClass.Code starts with a value of 100. It then checks if that Code exists with the method CodeExists(). If it can't find the code it should set SomeClass.Code = null.
But when i step through this piece of code with the debugger then i see that SomeClass.Code doesn't change at all, eventhough the debugger comes inside the if statement.
When i look at the property Code i see that it is declared as virtual:
public virtual CodeNumber Code { get; set; }
Does that mean i cannot simply change the value when it is declared as virtual? Is there anything i can do to change that value of Code?
Seems some other part of the code is the problem:
public SomeClassProjection SomeClass
{
get
{
// some stuff is done here
SomeClassState.Value = queryProcessor
.Execute(new ExistingProductsQuery { OrderNumber = SelectedOrderNumber });
return SomeClassState.Value;
}
}
So SomeClassState is returned. And that is defined like this:
public ViewValue<SomeClassProjection> SomeClassState;
So it does use another class like some of you suggested. And ViewValue clearly tells it is readyonly. That means i have to take another approach, but at least i now know what actually is prevents me from editting that property and that virtual has nothing to do with it.
About this topic:
So how do i accept an answer now that i found the solution? Or do i need to close this topic?

Seems some other part of the code is the problem:
public SomeClassProjection SomeClass
{
get
{
// some stuff is done here
SomeClassState.Value = queryProcessor
.Execute(new ExistingProductsQuery { OrderNumber = SelectedOrderNumber });
return SomeClassState.Value;
}
}
So SomeClassState is returned. And that is defined like this:
public ViewValue<SomeClassProjection> SomeClassState;
So it does use another class like some of you suggested. And ViewValue clearly tells it is readyonly. That means i have to take another approach, but at least i now know what actually is prevents me from editting that property and that virtual has nothing to do with it.

Related

Why does a property called DefaultStringValue always appear first in IntelliSense?

If you define the following class:
public class Test
{
public string Something { get; set; }
public string AnotherThing { get; set; }
public string DefaultStringValue { get; set; }
}
then, when you list the properties with IntelliSense, DefaultStringValue appears first in the list, despite this not being in alphabetical order:
If you change the property name to anything else, normal service is resumed:
Anyone know why this is? I'm curious...
(Note: I'm also using Resharper Ultimate 2018.1.2)
This is IntelliSense (and/or ReSharper) being, well, intelli-gent, and trying to help you re-use things you've used previously. If you start again from nothing, you'll find that things are alphabetical:
I'm betting that at some point in the past, you've made use of the DefaultStringValue property, and not the others, so it's suggesting it first:
Having renamed it, if you enter the line t.DefaultStringValu = "x";, then delete it again, next time you enter t. and invoke IntelliSense, DefaultStringValu will now be top of the list:

Using Getters and Setters in Unity

I have another question about this with getters and setters. Now that I started working with c# getters and setters as I understood them. The problem I see is that why should I make public variable that looks like this:
// Variable
private int _iRandomNumber
// Getter and setter
public int iRandomNumber
{
get { return _iRandomNumber; }
set { _iRandomNumber = value; }
}
I don't see the point of that since what different would it then be to just make the variable public since it's anyway got the get and set in the same bracket?
However if I do like this:
// Variable
private int _iRandomNumber
// Getter and setter
public int GetiRandomNumber { get { return _iRandomNumber; } }
public int SetiRandomNumber { set { _iRandomNumber = value; } }
Then when I try to use my SetiRandomNumber by itself Unity complier complains that I cannot use my SetProperty since I do not have a GET property inside my SET. Should I really have to make it like the first example I wrote because as I wrote then what's the point of Getters and Setters in c#?
Or should I instead move away from them, like I asked from the beginning and make functions for each Get and Set like in c++ so I can actually use them by themself?
Sorry for making this a new question, however it was not possible to add this as a comment in my previous question since it was to long.
Properties allow you to fire events when values are set, for instance:
public string Name {
get { return name; }
set {
name = value;
var eh = NameChanged; // avoid race condition.
if (eh != null)
eh(this, EventArgs.Empty);
}
}
private string name;
public event EventHandler NameChanged;
An added bonus is that you can track when your property gets set or read by putting breakpoints in the getter/setter with your debugger or diagnostic print statements.
I don't see the point of that since what different would it then be to just make the variable public since it's anyway got the get and set in the same bracket?
The difference is that you're separating your implementation detail (a field) from your API (the property). You could later change the implementation, e.g. to use one long variable to serve two int fields. (That's just one random example.) Or you can provide validation and change notification in the setter. Or you can perform lazy computation in the getter. Or you can make the property read-only from the outside, but writable privately. The list goes on.
Your second code declares two different properties - one read-only, and one write-only, both backed by the same variable. That's non-idiomatic C# to say the least, and gives no benefit. There's no linkage between those two properties, whereas in the first version there's a clear link between the getter and the setter as they're parts of the same property.
One thing to note is that your first example can be more concisely expressed with an automatically implemented property:
// Removed unconventional "i" prefix; this follows .NET naming conventions.
public int RandomNumber { get; set; }
That creates a private variable behind the scenes, and a public property whose getter and setter just use the private variable. Later if you want to change the implementation, you can do so without affecting the API.
The advantage of getters and setters is that they mainly act as functions so you can do something like this
private int _iRandomNumber;
public int iRandomNumber
{
get { return _iRandomNumber%10;} //you can do something like this mod function
set { _iRandomNumber = value+1000;} //you can manipulate the value being set
}
But if you do not have this kind of requirements on your variables, you might as well use just a public variable.

ProductName hides System.Windows.Forms.Control.ProductName

I have a property ProductName in my Form. I am getting warning while compiling the code.
FormInventory.ProductName hides inherited member 'System.Windows.Forms.Control.ProductName'. Use the new keyword if hiding was intended.
below is my code
public partial class FormInventory : Form, IInventoryView
{
public FormInventory()
{
}
public string ProductName
{
get { return this.textProductName.text; }
set { this.textProductName.text = value; }
}
}
textProductName is a textbox.
I know that ProductName hides the base class's property Forms.Control.ProductName. My question is
Is it possible to suppress the warning without Renaming my FormInventory.ProductName property
I am currently in the beginning of the development, if i hide this property with the new modifier will there be any problem at the time of releasing the product, because base property Forms.Control.ProductName returns the product name of the assembly containing the control. Where as my FormInventory.ProductName returns a user entered value.
Where will we be using this Forms.Control.ProductName, because i have never used it before.
I have searched and found Similar questions
Entity Framework hides inherited member Warning
Use new keyword if hiding was intended
these questions doesn't solve my problem but helped me in understanding the cause for the warning.
If ProductName is a form field that you intend displaying on the form, why not instead abstract all the fields of property into a separate Product entity. This should ease the maintenance of your app (and bring it more in line with patterns like MVC / MVVM), e.g.
public class Product
{
public string ProductName{ get; set; }
public int ProductSize{ get; set; }
// etc
}
public partial class FormInventory : Form
{
public FormInventory()
{
}
public Product Product
{
get;
set;
}
}
Edit :
IMO, the architecture presented by Rod Cerata's blog looks OK, but I believe it would be improved via encapsulation of a "ViewModel" for your Employee.
Have a look at EmployeePresenter.cs - you get lots of repetitive scraping code like this:
_model.EmployeeID = _view.EmployeeID;
_model.Lastname = _view.Lastname;
_model.Firstname = _view.Firstname;
_model.EmployeeType = _view.EmployeeType;
_model.Salary = _view.Salary;
_model.TAX = _view.TAX;
IMO would be improved by creating a new EmployeeViewModel class (which would be more or less the same as EmployeeModel, plus any 'screen' specific fields e.g. Title, "mode" (Edit, New, Read Only etc), and then using a tool like AutoMapper, which would reduce the code above.
1. Yes, simply use the new keyword, like public new string ProductName { get; set; }
2. No, it simply returns the name of the assembly.
3. Its used for debugging and some "reflection". I say "reflection" because it's more like a human-made reflection.
So, it's safe to go forward this way. But why don't you simply change it to MyCompanyProductName?
Regards
Using the 'new' keyword will suppress the warning. When you do this, the result of calling the ProductName property depends on Type of the variable that is used to referenced the form... for example, if you're calling the property from another class:
// Notice that we're only creating one object and
// assigning it to two different variables.
FormInventory explicitlyNameForm = new FormInventory();
Form referenceToBaseForm = explicitlyNameForm;
// Acting on the child reference (FormInventory) will
// operate on YOUR implementation of ProductName
explicitlyNameForm.ProductName = "Some Value";
// But acting on the parent reference (Form) will
// operate on the .NET implementation of ProductName
referenceToBaseForm.ProductName = "Some Other Value";
The end result will probably be what you want... the compiler knows which implementation to use based on how you've declared your variable. And since all references within the .NET framework reference the Form class, not your new class, there is no risk of affecting anything that happens within the .NET framework with respect to this property.
However, as the others have suggested, it may cause less confusion if you're able to rename the property.

Elegant ways of avoiding numerous code changes in the following legacy code

In some legacy code, there are hundreds of occurrences of the following code snippets:
myObj.ReportGenerator.Preview = reportingObj.PreviewDocument;
... whereas both the "ReportGenerator" and the "ReportingObj" are instances of a third party library and therefore not modifyable.
This code did work well under Windows XP, but running the program in Windows 7 does require the following additional line of code:
reportingObj.Render();
myObj.ReportGenerator.Preview = reportingObj.PreviewDocument;
Unfortunately, there are hundreds of occurences of this piece of code all of the code base, and manually searching for them sounds like quite error-prone a process.
As "ReportGenerator" and "reportingObj" are third party, I cannot change their getter / setter.
What are elegant ways of approaching such an issue?
You could wrap ReportingObj in a class of your own in which you just delegate to the original ReportingObj, but for the PreviewDocument property check to see if Render() was called and if not call it - something like this:
public Foo PreviewDocument
{
get
{
if (!_rendered)
{
_originalreportingObj.Render();
_rendered = true;
}
return _originalreportingObj.PreviewDocument;
}
}
You could change the class of myObj, which I assume is under your control, and have the ReportGenerator property return a wrapper class that either calls the original setter of the Preview or calls it after calling Render():
public class ReportGeneratorWrapper
{
private ReportGenerator m_InnerReportGenerator;
public PreviewDocument Preview
{
get
{
return m_InnerReportGenerator;
}
set
{
if (IsNT6OrAbove)
value.Render();
m_InnerReportGenerator = value;
}
}
}
You might find that the least amount of rework will be to create a static class, something like:
public class Previewer
{
public static PreviewDocumentType PreviewDocument(ReportingObject reportingObj) {
reportingObj.Render();
return reportingObj.PreviewDocument;
}
}
where PreviewDocumentType is the type returned from PreviewDocument and ReportingObject is the type of reporting object.
You can then replace
reportingObj.PreviewDocument;
with
Previewer.PreviewDocument(reportingObj);

Will my object update the way I think it will update using this method (C#)?

This might seem like a CS101 question, but I've managed to thoroughly confuse myself.
//this is inside a service class
ObjectToUpdate objectToUpdate = objectrepository.Get(objectToUpdate.Id);
SecondObject secondObject = secondObjectRepository.Get(secondObject.Id);
objectToUpdate.Update(secondObject);
objectRepository.Save(objectToUpdate);
//the object itself
public class ObjectToUpdate {
public int Id { get; set; }
public string Name { get; set; }
public void Update(SecondObject secondObject) {
Name = secondObject.Name
}
}
When I get to the "Save" line, it will correctly have updated the objectToUpdate with the name from the secondObject, correct? It carries a reference to itself when you pass it to the Update method?
Yes, classes are passed around by reference, so you will be passing a reference to the same object. This tutorial provides a great reference for understanding this concept: http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx?ArticleID=9adb0e3c-b3f6-40b5-98b5-413b6d348b91&PagePath=/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.aspx
That looks correct to me. When you get to the Save() line, objectToUpdate.Name will be the same as secondObject.Name
If it is easier to read logically, you could change this line to include "this."
this.Name = secondObject.Name
so that you realize that the Name property being set is the one that belongs to 'this' which is the same object instance that the method was called on. The code is functionally identical, but might be easier to comprehend?
Yes, the value of a .NET Object is actually the memory address where that object is stored. Saying firstObject = secondObject wouldn't affect the secondObject referenced in the calling method, but saying firstObject.Name = secondObject.Name will change the value of the Name.

Categories