I've seen the following code in various places:
namespace My.name.space
{
class myClass
{
public CustomObject Name
{
get { return new CustomObject (this.Dog); }
set { return; }
}
}
}
What is the purpose of set { return; }?
I don't understand what purpose set return would serve.
I would think you could just remove the set accessor completely.
None. It's somebody who doesn't quite know that a read-only property can be expressed much more simply by not including the set
public Derp MuhDerp { get { return _derp; } }
Interesting point brought up by CSharpie in a comment...
If you have to have a set because it is defined in an interface, you can add the set but omit the return:
public Derp MuhDerp { get { return _derp; } set { } }
Of course, if the interface defines a setter, you should probably make sure it works as expected :)
It is basically to give the illusion that there is a setter, well there is, but does nothing. But it was probably done to keep some interface happy or a parent class:
public CustomObject Name
{
get { return new CustomObject( this.Dog ); }
set { return; } // does absolutely nothing
}
Here is a class:
public abstract class A {
public abstract void DoWork();
public abstract string SomeProperty { get; set; }
}
Here is giving the illusion that it is implementing the abstract interface, but it really is not implementing everything:
public class B : A {
public override string SomeProperty
{
get
{
return "whatever";
}
set
{
return; // keep interface happy
}
}
public override void DoWork() {
// I am not doing nothing but compiler is happy
}
}
That code also breaks Liskov Substitution Principle.
That simply means "don't do anything, I don't want to make an assignment". It's like a no-op in the setter. It's also equivalent to an empty setter, i.e. set { }. It's a matter of preference, really; some people prefer not to have empty code bodies, I guess.
Of course, you wouldn't typically do it that way (as Will points out). You would just use a read-only property, but there is a key difference: when using a read-only property, an attempt to set it will fail at compile time; if you're using the one you asked about, then it won't fail at all, it will simply "do nothing" at runtime.
Which one you use largely depends on what you want your application to do. I'll point out that using this approach (rather than a read-only property) can lead to brittle code, as the programmer may not be aware that their deliberate attempt to assign a value is being ignored.
Properties in C# are just syntax candy for a special case of methods.
A "regular" property like
public int Foo {get;set;}
is actually (sommething similiar)
int _foo;
public int get_Foo() { return _foo;}
public void set_Foo(int value) { _foo = value;}
However you are allowed to speficy yourself, what happens in the setter and getter
public int Foo { get { return 47; } set { Console.WriteLine(value); } }
So taking your example the compiler will turn it into
public CustomObject get_Name() { return new CustomObject (this.Dog); }
public void set_Name(CustomObject value) { return; }
Which does nothing in the set-Method at all. So why would someone do this?
There are a few reasons that make sense:
They want to later introduce functionality to that setter, so it serves as a placeholder for now
The setter is required, because the Property comes from an interface, yet it makes no sense to set the value in that concrete implementation
Some API or stuff based on reflection requires a set-method even if it is not used.
this is the same as a read only property, but the property can be setted (obviously with no sense).
There are some great answers here (and I know this is an old question), but I wanted to provide some additional context for what this is, when it might be useful, and how I've used it in production code.
First, the answer: This is normally not useful. Just define a readonly property. As others have said, you're completely right that you could remove the set and have almost the same effect -- except that the property could no longer be assigned to.
Now, here's where this can be useful. For a lot of the smaller microservices I write, I use Azure Tables for storage. This is a key-value database, where your key comes in two parts: a PartitionKey and a RowKey. They're pretty self-explanatory.
Generally I'll end up with a couple of small tables (such as ones holding basic application-managed settings) that don't make sense to use a PartitionKey with -- i.e. they only have one identifying piece of information, such as an id, along with a value.
The Azure.Data.Tables library is really nice, and provides an interface to implement for your DTOs. Implementing this interface would normally look like the following:
using Azure;
using Azure.Data.Tables;
namespace SmartsheetIntegration.Qar.DataStores.Models;
public class MyDto : ITableEntity
{
public MyDto() {}
public MyDto(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
}
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Now, what about these simple app settings? I want to make sure that they never end up with a PartitionKey, because I need to know for sure that if I want to retrieve all of them, I can query for 'PartitionKey = ""' and get everything back.
The simple solution to this is:
using Azure;
using Azure.Data.Tables;
namespace SmartsheetIntegration.Qar.DataStores.Models;
public class MyDto : ITableEntity
{
public MyDto() {}
public MyDto(string partitionKey, string rowKey)
{
PartitionKey = partitionKey;
RowKey = rowKey;
}
public string PartitionKey
{
get => "";
set { } // the same as set { return; }
}
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Now Azure Tables can do whatever it wants in its library, but I can guarantee that the PartitionKey saved to the database will always be an empty string.
So yes, the number of situations where this is useful isn't huge -- but there are interface implementations where it makes sense.
Related
I want to pass in an instance of an interface to an object and initialise all the values of this object to those of the object passed in where both objects implement the same interface? Are there any good shortcuts in this particular case where they share an interface. It seems to me there must be... I just can't recall ...
EDIT: After John's feedback, the question is better expressed as - How do I pass in an instance of an interface to an object's constructor and initialise all the values of this object to those of the interface instance passed in?
Most deep copying solutions (including my own previous solutions) return an object - which is not going to work in a constructor, or rely upon creating a new instance (which is not going to work with an interface as the source and destination).
I want to pass in both source and destination and have properties of the source copied to the destination where they are both interfaces. Is there an existing solution for this. Or do I revisit my own code and try to adapt it - my previous own solution from 2009 (with minor bug corrected in the answers) SetValue on PropertyInfo instance error "Object does not match target type" c# AND svics answer in transfering one object properties values to another one suffice for the simple cases where all properties are just values.
e.g.
public interface ISomething
{
...
}
public class A : ISomething
{
public A(ISomething input)
{
// what goes here??
}
}
I'm not really sure I fully understand your restrictions, but for most object copying work I use AutoMapper, which greatly helps with the grunt work of copying objects. It means a different approach than copying properties in constructors, but maybe useful. Here's some example code:
public interface ISomething {
string MyProperty { get; set; }
int AnotherProperty { get; set; }
B ClassProperty { get; set; }
}
public class A : ISomething {
public string MyProperty { get; set; }
public int AnotherProperty { get; set; }
public B ClassProperty { get; set; }
}
public class B {
public string BProperty_1 { get; set; }
public int BProperty_2 { get; set; }
}
class Program {
static void Main(string[] args) {
// Configure the mapping
Mapper.Initialize(cfg => cfg.CreateMap<ISomething, ISomething>());
// Initialize first instance
var firstA = new A {
MyProperty = "Test",
AnotherProperty = 21,
ClassProperty = new B {
BProperty_1 = "B String",
BProperty_2 = 555
}
};
// Initialize second instance and perform the mapping
var secondA = Mapper.Map<ISomething>(firstA);
Here, all the properties in firstA are copied over to secondA, including the properties in ClassProperty.
The mapping configuration is performed once on startup, and uses recursion and reflection to build the mapping model. It can then be used anywhere in your code. If new properties are added to the interface, the mapping configuration stays the same.
Simply set all the properties of the interface in the constructor:
public class A : ISomething
{
public A(ISomething input)
{
A.MyProperty = input.MyProperty;
A.AnotherProperty = somethingNotFromTheInterface
}
}
This is called a copy-constructor. Wheather this actually creates a deep or a shallow copy of your existing instance depends on if it contains references to other reference-types. In this case you´d have to re-create all those instances also:
public A(ISomething input)
{
A.MyProperty = new MyType(input.MyProperty);
A.AnotherProperty = somethingNotFromTheInterface
}
Which itself assumes you hacve a copy-constructor for the type of MyProperty also.
This can become some huge task when your interface is quite big. You may consider looping all the interfaces properties with reflection in this case, or even better rethink if your interface is actually serving a single purpose and not doing too much.
I am learning C# and i have encounter the following piece of code
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
just wondering what's the different with the following? i mean without the get and set you can access those public property as well. what's make it important to have those get and set?
public class Album
{
public virtual int AlbumId;
public virtual int GenreId;
public virtual int ArtistId;
public virtual string Title;
public virtual decimal Price;
public virtual string AlbumArtUrl;
public virtual Genre Genre;
public virtual Artist Artist;
}
To have control over your object private fields values. for example if you don't wanna allow nulls or negative values for integers.
bool started;
public bool Started
{
get { return started; }
set
{
started = value;
if (started)
OnStarted(EventArgs.Empty);
}
}
another example
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
set {
if (value < 0)
positiveNumber = 0;
else positiveNumber = value;
}
}
and also another implementation of read only properties could be as follows
int positiveNumber;
public int PositiveNumber
{
get { return positiveNumber; }
}
You can't declare a virtual field
public class Album
{
public virtual int AlbumId; // <- Syntax error
...
}
properties are, in fact, methods: get or(and) set, so
public class Album
{
public virtual int AlbumId { get; set; } // <- Both get and set methods declared as virtual ones
...
}
And you can override these get's or(and) set's in derived class if you want:
public class GreatAlbum: Album {
private Boolean m_IsGreat;
public override int AlbumId {
get {
if (m_IsGreat)
return base.AlbumId
else
return 0;
}
set {
m_IsGreat = (value != 0);
base.AlbumId = value;
}
}
...
}
With providing get(accessor) and set(mutator) methods, you can control accessing and mutating.
For example:
You have a property that you don't want to be set any value more than 15. So u make required restrictions in your set method. Unless that set method, you can't control.
But in your example, your get and set methods are default, means controlling nothing.
The main reason behind properties is to protecting and presenting private data in a controlled way.
In fact, properties show their abilties in the usage like this:
public virtual int AlbumId
{
get { // ... some magical operations ... }
set { // ... some magical operations ... }
}
And about your main question - what's the difference in this example - the main point to attention is the virtual keyword.
This keyword causes the property to be overrideable, So any other code could override the default get; method. It meens that you have the default behavior for yourself, and other codes (Extremely used in Entity Framework) implement their own logic!
Those second ones in your example aren't properties, so they don't express this magical ability...!
In the first case you are dealing with properties, in the second with fields.
Using fields has several drawbacks when compared to using properties. These drawbacks include:
You can set a breakpoint in a get or set of a property, but you can not set a breakpoint on access to the field.
Making fields public violates the information hiding principle.
The binary MSIL code for accessing fields and properties is different, so if you change a public field to a public property in the future, although the source code stays compatible, any dependant binary code breaks.
The code required to use reflection is different, hence when you move from a field to a property, your reflection code will break.
To cut a long story short: Always use public properties, NEVER use public fields.
There are a number of differences:
Properties are turned into methods by the compiler. As such, you can declare them virtual and override them in a derived class.
Using properties, you can put logic in the getter or setter (filtering, validation etc).
When you use automatically implemented properties ({ get;set;}), it may seem that you might as well just use public fields. However, using properties means you can change your getter or setter implementation at a later time, without changing the interface your class is exposing. If you had used a field and wanted to implement filtering whenever that field was read, you would have to introduce a new method, make the field private and break all existing consumers of the type.
Personally, I think the automatically implemented properties promote bad style, because they do not encourage encapsulation. Tools like ReSharper also like to generate properties with {get;set} accessors. Novice developers thus typically end up with classes with lots of {get;set;} properties exposing the type's state to the world. You should at least use {get; private set;} by default.
I have a group of POCO classes:
class ReportBase
{
public string Name { get; set; }
public int CustomerID { get; set; }
}
class PurchaseReport : ReportBase
{
public int NumberOfPurchases { get; set; }
public double TotalPurchases { get; set; }
public bool IsVip { get; set; }
}
class SaleReport : ReportBase
{
public int NumberOfSales { get; set; }
public double TotalSales { get; set; }
}
I have a web method to return ReportBase. The caller uses the return value to update UI(WPF) based on the actually type by downcasting and checking the type (one grid for sale and one for purchase). Someone suggested to use three web methods and each return the specific type.
I understand that downcast is in general against design principle by introducing if/else. Instead we should use virtual functions. But in POCO class, we don't really have virtual behaviors (only extra fields).
Are you for or against downcast in this case, why?
IMO it's all about intention. Returning just the base class doesn't say anything, especially as you return it only to save some key strokes. As a developer what do you prefer?
ReportBase GetReport() // if type==x downcast.
//or
PurchaseReport GetPurchaseReport()
SaleReport GetSalesReport()
What approach would you want to use to make the code more maintainable? Checking type and downcasting is an implementation detail after all and you probably have a method like this
public void AssignReport(ReportBase report)
{
//check, cast and dispatch to the suitable UI
}
What's wrong with this? It's lacking transparency, and this method should always know about what reports are needed by what UI elements. Any time you add/remove an element you have to modify this method too.
I think is much clear and maintainable something like this
salesGrid.DataSource=repository.GetSalesReport();
purchaseGrid.DataSource=repository.GetPurchaseReport();
than this
var report=repository.GetReport();
AssignReport(report); //all UI elements have their data assigned here or only 2 grids?
So I think that, POCO or not, I will favour the three web methods approach.
In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}
I understand how the "new" keyword can hide methods in a derived class. However, what implications does it have for classes that implement interfaces that use the keyword?
Consider this example, where I decide to expand an interface by making its properties read/write.
public interface IReadOnly {
string Id {
get;
}
}
public interface ICanReadAndWrite : IReadOnly {
new string Id {
get;
set;
}
}
Then you are able to do things like this:
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
Is this bad design? Will it cause issues for my classes that implement ICanReadAndWrite?
Edit: Here is a contrived example of why I might want to do something like this:
Say I have a factory class that returns an IShoppingCartItemReadWrite. I can then have a service layer that manipulates prices on it, changes stuff, etc. Then, I can pass these objects as IShoppingCartItemReadOnly to some kind of presentation layer that won't change them. (Yes, I know it technically can change them-- this is a design question, not security, etc.)
It's not a particularly bad idea. You should be aware that the implementor can (if it implicitly implements the interface, then a single read/write property could satisfy both interfaces) provide two distinct implementations:
class Test : ICanReadAndWrite {
public string Id {
get { return "100"; }
set { }
}
string IReadOnly.Id {
get { return "10"; }
}
}
Test t = new Test();
Console.WriteLine(t.Id); // prints 100
Console.WriteLine(((IReadOnly)t).Id); // prints 10
By the way, in general, the new inheritance modifier does nothing except to tell the compiler to shut up and don't throw out a "you're hiding that member" warning. Omitting it will have no effect in the compiled code.
You should not implement the ICanReadWrite based on IReadOnly, but instead make them separate.
ie. like this:
public interface IReadOnly
{
string Id
{
get;
}
}
public interface ICanReadAndWrite
{
string Id
{
get;
set;
}
}
Here's a class using them:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
}
Note that the same property in the class can support both interfaces.
Note that as per the comment, the only way to get a robust solution would be to also have a wrapper object.
In other words, this is not good:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return this;
}
}
as the caller can just do this:
ICanReadWrite rw = obj.AsReadOnly() as ICanReadWrite;
rw.Id = "123";
To get a robust solution, you need a wrapper object, like this:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return new ReadOnly(this);
}
}
public class ReadOnly : IReadOnly
{
private IReadOnly _WrappedObject;
public ReadOnly(IReadOnly wrappedObject)
{
_WrappedObject = wrappedObject;
}
public string Id
{
get { return _WrappedObject.Id; }
}
}
This will work, and be robust, right up until the point where the caller uses reflection.
This is perfectly legal and the implications for your class that implements the ICanReadAndWrite interface would simply be that when it is treated as an IReadOnly it can only read, but when treated as ICanReadAndWrite it would be able to do both.
I'm not sure if that compiles or not, but is not an advisable pattern to follow. With the ability to do explicit interface implementation, you could theoretically provide two entirely different implementations for the IReadOnly and ICanReadAndWrite versiond of the Id property. Consider altering the ICanReadAndWrite interface by adding a setter method for the property rather than replacing the property.
You can do it but I am not sure what you hope to accomplish by doing it.
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
This method will return a reference to an IReadOnly which means that it doesn't matter that you have returned an ICanReadAndWrite. Wouldn't this approach be better?
public interface IReadOnly
{
String GetId();
}
public interface ICanReadAndWrite : IReadOnly
{
String SetId();
}