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.
Related
I want to dynamically add attributes to properties of a given class, because the project will get bigger and the procedure is totally repeatinglly, something like so :
public class MyAttr : Attribute {
public MyAttr () {
foreach(var prop in properties) {
prop.Attributes.Add([Display(Name = nameof(prop.Name), ResourceType = typeof(Labels))]);
}
}
}
And use it on classes :
[MyAttr]
public class SomeClass {
public string Name {get; set;}
public string Description {get; set;}
}
of course the code above is not a real program, but I tried to make it simple.
Is it possible to do this? or if not, is there a workaround?
Update: I know there's an attribute called CallerMemberName that retrieves name of a given property, but how to get the property itself and add more attributes to it?
I think you might be able to make something work combining the below answers from other posts.
Access object properties from Attribute: Can C# Attributes access the Target Class?
Add attributes at runtime: How to add an attribute to a property at runtime by creating new types at run-time.
Unless you're going to be making regular changes across all the properties it may just be better to deal with the repetitive work up front. There are inevitably risks/issues down the road when doing stuff across the board like this.
First of all, I have read the question asking for the difference between fields and properties and I know what it is used for.
Now on to my question, I wanted to create a property where I am sure that get and set will both be empty, so I do get; set;. All good and well. But now I realised that I have just made a public field with a capital name, it is in all ways identical.
Even the argument of it being used so future code does not depend on implementation cannot be said, as I can simply make this a property and implement a getter or a setter. The semantics of a field and a property are identical outside the class it is defined in.
So my question is, should I use a field or a property when a property would simply use get;set;?
So this:
public IEnumerable<string> Products;
is identical in all ways to this:
public IEnumerable<string> Products { get; set; }
should I use a field or a property when a property would simply use get;set;?
Use a property... for the practical reasons below, and for the philosophical reasons that properties expose a state API, whereas fields expose a state implementation detail.
The semantics of a field and a property are identical outside the class it is defined in.
That's not true.
The difference is visible via reflection, which is often very important. For example, many binding frameworks won't use fields, only properties.
You can pass a mutable field by ref, but not a property - so changing a field to a property breaks source compatibility. (Code using SomeMethod(ref x.Products) will become invalid when Products becomes a property.)
Changing a field to a property also breaks binary compatibility, so if assembly X was built against assembly Y v1.0, and you change a field to a property for assembly Y v1.1, then you'd need to rebuild assembly X or it would fail to execute correctly
If you have a mutable value type (please don't do this) then writing foo.Location.X = 10 works when Location is a field (because x.Location is classified as a variable) whereas it doesn't when Location is a property (because then the expression x.Location is classified as a value). If you have a method (in your evil mutable type) which mutates the value instead, then foo.Location.DoSomething() will compile in both cases, but have a different effect. Fun for all the family.
Its depend on the situation. I'll prefer to use the property over the field. You have mentioned that public IEnumerable<string> Products; and public IEnumerable<string> Products { get; set; } are same, but in actual they are not. During compilation the property will get converted into two methods (i.e. get_Products() and set_Products()).
The advantage of property is to allows you to specify the custom code before assigning and returning the data, this is not possible with the field. Check the example below
public IEnumerable<string> Products
{
get
{
if(DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
{
//Return future product
return new List<string>();
}
else
{
// return current products
return new List<string>() { "testing" };
}
}
set
{
if (DateTime.Now.Date > Convert.ToDateTime("01-01-2016"))
{
//ignore assign product
Products = new List<string>();
}
else
{
// add assign product
Products = value;
}
}
}
Using the auto-property syntax is preferable because it creates a read/write property with a private backing field, thus allowing you to change the implementation (from a private scalar field to a dictionary entry or another backend with some other custom logic), thus freeing the "class's interface" (not the same thing as an interface) from its implementation.
Note that for collection member properties, it is advisable to make their setters private, like so:
public IEnumerable<String> Products { get; private set;}
...that way only the containing class can alter it.
Another alternative is the private readonly field, in C# 6 you can use auto-implemented properties with readonly backing fields like so:
public IEnumerable<String> Products { get; } = SomeSource.GetProducts();
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.
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.
I've never really questioned this before until now. I've got an input model with a number of fields, I wanted to present the string names of the properties through the input model so that my Grid can use them:
public class SomeGridRow
{
public string Code { get;set; }
public string Description { get;set; }
public const string Code = "Code";
}
Obviously, this gives the error:
The type 'SomeGridRow' already
contains a definition for 'Code'
Why can the CLR not cope with two properties of the same name which are, in my eyes, separate?
string code = gridRow.Code; // Actual member from instantiated class
string codeField = SomeGridRow.Code; // Static/Const
I'm now just using a child class called Fields within my inputs now, so I can use SomeGridRow.Fields.Code. It's a bit messy, but it works.
Because you can also access static (or, non-instance in this case) properties in the same way (inside the same class), and it would be a bit confusing, for example:
public class SomeGridRow
{
public string Code { get;set; }
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
Because both this:
public class SomeGridRow
{
public string Code { get;set; }
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
And this:
public class SomeGridRow
{
public const string Code = "Code";
public void MyMethod() {
var thing = Code; //what would this reference?
}
}
are valid ways to access properties, static or not. It doesn't answer the "why can't I?" question, but more of the why it's not allowed...it would be far too ambiguous IMO.
It probably could, but the designers of C# wanted to avoid ambiguities that can come from such use (abuse?) of language features.
Such code would end up being confusing and ambiguous to users (did I want the instance or the static method call?, Which one is right?).
In addition to the points already made about ambiguity, i would say that the naming needs to be relooked in such a case.
If two variables / fields having the exact same name in the same context i.e class but different values to me sounds more like a naming issue.
If they are exactly same, you dont need 2 fields.
If they are slightly different, you should have more accurate names.
In some other languages with a similar syntax, one can access a static member through an instance. So you could access both string.Empty and "abc".Empty.
C# doesn't allow this (though it does sort of from inside the class or a derived class, in that you can omit the class name for a static member and can omit this for an instance member), primarily to avoid confusion (I find it more handy than confusion tbh, but that's just me, I like switch fall-through too so what do I know).
Having introduced a stricter rule to allow for less ambiguity, it would be counterproductive to allow a new looser rule on the back of it that allowed for more. Think how many "why must I use this with property X but not property Y?" questions SO would have if it was allowed (we'd have to force this with property X to be clear we meant the instance member).