Auto properties with different accessors in an Interface - c#

is there any diffrence between this 3 auto properties ?
interface MyInterface {
public int p1 { get; set; }
public int p2 { get; }
public int p3 { set; }
}
also why we can write this code in an interface but not in a class ?
public int p { get; }

For the same reason you can write this in an interface:
interface IFace {
void Test();
}
Also, your interface is invalid, as public isn't valid in an interface. The point being, different things are legal in interfaces and classes.
When you do public int P1 { get; set; } in a class, that turns into a auto property. However, you can't do public int P1 { get; }, because what would you want that to mean? Should it always return 0? There is no way to set it. So if you want a read only property you have to define the getter yourself like this:
int _p1;
public int P1 {
get { return _p1; }
}
Also. Another way to achieve more or less the same is this:
public int P1 { get; private set; }

There are differences between those properties. Firstly, you should remove the public modifier from your declaration. Secondly, by putting get or set within the block you define what properties in derived classes should look like. For example, public int p1 { get; set; } requires getter and setter in a derived class, public int p2 { get; } only getter, and public int p3 { set; } requires only setter to be implemented.
You can't use access modifiers inside interfaces because interfaces are guidelines for other developers that force them to go in a certain direction when developing the implementing classes.
Look at this post for more information about that.

Keep in mind interface does NOT contain any implementation data. When you add property in an interface, it merely says that a class implementing this interface needs to have said property with get, set or both methods, depending on what you wrote. So any class implementing your interface has to implement (or have auto-generated) p1 property with get and set method, p2 with get method, and p3 with set method. Interface doesn't care whether these will be auto-generated or your own custom implementations, they just have to be in an implementing class.
Therefore, you can write
int p { get; }
in an interface as all it does is telling that any class implementing this interface has to have property p with getter, again, not caring about its actual implementation - you could write a getter that does some computations, returns some constant, etc. OTOH in a class writing the same would mean that you want a property with auto-generated backing field, except since it would have no setter, you couldn't actually change its value, so it would always have its default value 0.
And as noted, you cannot write access modifiers in an interface, as all interface members are implicitly public.

Related

Is there a way to hide or override a base class member variable (itself a class) in its derived class in C#?

I have an app that uses a set of dll's from a 3rdparty. I am trying to incorporate an updated version of the dll's that have changed some variables and parameters from int to uints. I think I can easily capture base class events in my derived class and re-throw modified events, but I am not sure of an easy way to handle the direct access of the variables in the base class's member class.
The example below shows the original 3rd party implementation. In the latest version, the member variables of ThirdPartyNumberPair are now uint's. I'm looking for a way to intercept the MyNumberPair.x and .y access in my derived container and do the conversion so I don't have to modify SomeMethod - mainly because it is used in many places.
public class ThirdPartyNumberPair
{
public int x{ get; set; };
public int y{ get; set; };
}
public class ThirdPartyContainer
{
public ThirdPartyNumberPair MyNumberPair;
}
public class MyDerivedContainer : ThirdPartyContainer
{
...
}
public class MyClass
{
public MyDerivedContainer myContainer;
public void MyMethod(){
int i = myContainer.MyNumberPair.x;
myContainer.MyNumberPair.y = 3;
}
}
I've tried creating a derived MyThirdPartyNumberPair and hiding the base ThirdPartyNumberPair, but I didn't find any easy way of getting those values to the base ThirdPartyNumberPair member.

In c# how to prevent a class from being modified

Let's say I have an interface:
interface IPerson
{
int Age { get; set; }
string Name { get; set; }
bool Alive { get; set; }
}
and a Class:
public class Person : IPerson
{
public int Age { get; set; }
public string Name { get; set; }
}
That would not compile since Person does not implement the Alive Property.
What I would like to know is if there is a way to have the same behaviour, if Person adds an extra property that is not found in its interface.
interface IPerson
{
int Age { get; set; }
string Name { get; set; }
}
and a Class:
public class Person : IPerson
{
public int Age { get; set; }
public string Name { get; set; }
public bool Alive { get; set; } <---- This should prevent it from compiling as well.
}
I would want it to not compile as well, or at the very least give me a compile warning.
No. Interfaces define what members an object must implement. They cannot define members that an object can't implement. You could potentially use your own custom, or third party code analysis tools, to identify cases like this, but there is nothing in the language itself that would support it.
No it is not possible. Are you not trying to define a class itself here? Why do you really need an interface?
However, what you can achieve is make calls to your interface and not your class by doing
IPerson person = new Person();
this way you limit the person object to access only the methods defined in your interface.
There is a way to do this, but not within the object and its a bit silly to use in construction of the object. Using Reflection, you can check the type of an instance of your object and iterate through its properties, throwing an exception if the count or names of properties do not match your desired instance. Please note that if you just check against the interface, implementing objects will pass, so you would check against the desired concrete type. I am on my phone or I'd add some sample code, will try to return to this later.
There is a way to do this, but not within the object and its a bit silly to use in construction of the object. Using Reflection, you can check the type of an instance of your object and iterate through its properties, throwing an exception if the count or names of properties do not match your desired instance. Please note that if you just check against the interface, implementing objects will pass, so you would check against the desired concrete type. I'm on my phone so no sample code. Will try to return to this later.

Adding setter to inherited read-only property in C# interface

I have an interface that declares some properties (shortened to Id only in the example) with only a get method. Classes implementing this interface do not have to provide a public setter for this property:
public interface IMetadataColumns
{
Int32 Id { get; }
}
Now I need another interface with the same properties, but now they must all be writable as well. So I added a new interface inheriting from the old one where each property also has a setter:
public interface IMetadataColumnsWritable : IMetadataColumns
{
Int32 Id { get; set; }
}
Visual Studio now underlines this and warns me to use the new keyword if hiding the old properties was intended.
What shall I do now? I have classes implementing the IMetadataColumns interface which need some of the properties to be read-only, but I also have other classes where exactly those same properties must be writable as well.
I guess hiding a property sounds somehow not like the way to go...
When interfaces are involved, the new keyword doesn't mean you are hiding the property in the same sense as with classes.
Your class implementing IMetadataColumnsWritable will only have one Id, regardless of whether you cast it to the base IMetadataColumns interface or not (unless you add an explicit implementation for the readonly property - but this is not needed and would only allow for errors in this case).
In other words, you might have:
// this interface is public, and it allows everyone to read the Id
public interface IMetadataColumns
{
int Id { get; }
}
// this one is writeable, but it's internal
internal interface IMetadataColumnsWritable : IMetadataColumns
{
// we need to use 'new' here, but this doesn't mean
// you will end up with two getters
new int Id { get; set; }
}
// internal implementation is writeable, but you can pass it
// to other assemblies through the readonly IMetadataColumns
// interface
internal class MetadataColumns : IMetadataColumnsWritable
{
public int Id { get; set; }
}
So, unless you explicitly implement the readonly property as a separate one, you will have only a single property, whichever interface you use to access it:
var columns = new MetadataColumns { Id = 5 };
var x = (columns as IMetadataColumns).Id;
var y = (columns as IMetadataColumnsWritable).Id;
Debug.Assert(x == y);
Hiding a member inside the class using the new keyword, on the other hand, is what I would not recommend in most cases, because it basically creates a completely new member, which just happens to be called the same as a different member in the base class.
You should indeed use the new keyword here. In your class implementation, you have to implement both properties (since you are not really hiding the property). If they have different return types, at least one of them has to be implemented explicitly.
public class X : IMetadataColumnsWritable
{
public int Id
{
get;
set;
}
// only necessary if you have to differentiate on the implementation.
int IMetadataColumns.Id
{
get
{
return this.Id; // this will call the public `Id` property
}
}
}
Does using explicit implementation of the getter only version forwarding to a public version work?
int IMetadataColumns.Id {
get {
return this.Id;
}
}
public Id {
get { … }
set { … }
}
You might find the public version does need to be new, but the explicit version will be picked up by references of type IMetadataColumns.

Internal Modifier on an Interface's Property

I have the following interface:
public interface IAgable {
int Age { get; internal set; }
}
I want the Age property, to be read-only for external assemblies that reference this interface, but also I want the Age property to be set on the interface's same assembly, hence the internal modifier.
This, however, seems to throw a compilation error, as accessibility modifiers may not be used on accessors in an interface.
I want the property to be called from an interface, and I want to be able to set it at an internal level. At the same time, if referenced from an outside project, I want it to be readonly.
Is this possible?
Have an internal interface that provides both a get and a set, and a public interface that provides only a get. Have the public interface extend the internal interface:
public interface IAgable
{
int Age { get; }
}
internal interface IAgableInternal : IAgable
{
int Age { set; }
}
This is not possible according to Microsoft
Interfaces declared directly within a namespace can be declared as public or internal and, just like classes and structs, interfaces default to internal access. Interface members are always public because the purpose of an interface is to enable other types to access a class or struct. No access modifiers can be applied to interface members.
http://msdn.microsoft.com/en-us/library/ms173121.aspx
Try this:
public interface IAgeable {
MyAge {get;set}
}
public class MyAge:IAgeable{
public MyAge(int age){
MyAge = age;
}
int MyAge { get; internal set; }
}

Alternative to calling a virtual method in C#

I am using NHibernate for my C# pojects and therefore I have several model classes.
Lets assume the following example:
using System;
namespace TestProject.Model
{
public class Room
{
public virtual int Id { get; set; }
public virtual string UniqueID { get; set; }
public virtual int RoomID { get; set; }
public virtual float Area { get; set; }
}
}
Mapping these objects with NHibernate works fine so far. Now I want to generate a new Room object and I want to store it in the database. To avoid setting each member seperatly, I add a new constructor to the model class.
Below the virtual members I write:
public RoomProperty()
{
}
public RoomProperty(int pRoomId, int pArea)
{
UniqueID = Guid.NewGuid().ToString();
RoomID = pRoomId;
Area = pArea;
}
Analyzing my code with FxCop tells me the following:
"ConstructorShouldNotCallVirtualMethodsRule"
This rule warns the developer if any virtual methods are called in the constructor of a non-sealed type. The problem is that if a derived class overrides the method then that method will be called before the derived constructor has had a chance to run. This makes the code quite fragile.
This page also describes why this is wrong and I also understand it. But I am not shure how to solve the problem.
When I erase all constructors and add the following method...
public void SetRoomPropertyData(int pRoomId, int pArea)
{
UniqueID = Guid.NewGuid().ToString();
RoomID = pRoomId;
Area = pArea;
}
.... to set the data after I called the standard constructor I cant start my aplication becaue NHibernate fails initializing. It says:
NHibernate.InvalidProxyTypeException: The following types may not be used as proxies:
VITRIcadHelper.Model.RoomProperty: method SetRoomPropertyData should be 'public/protected virtual' or 'protected internal virtual'
But setting this method to virtual would be the same mistake as when I just set the virtual members in the constructor.
How can I avoid these mistakes (violations)?
The problem lies in virtual set. Passing a value to the virtual property in the base class constructor will use overriden set instead base set. If overriden set relies on data in derived class, then you are in trouble, because constructor of derived class was not done yet.
If you are absolutely sure, that any subclass will not use any data of its state in overriden set, then you can initialize virtual properties in base class constructor. Consider adding an appropriate warning to the documentation.
If possible, try to create backing fields for each property and use them in base class contructor.
You can also postpone properties initialization to the derived class. To achieve that, create an initializing method in the base class that you invoke in constructor of derived class.
I expect one of the following to work:
Make the properties non-virtual (preferred as long as NHibernate supports it).
Change from auto-implemented properties to properties with an explicit backing field, and set the fields in the constructor instead of setting the properties.
Create a static Create method which constructs the object first, and then sets values to the properties before returning the constructed object.
Edit: From the comment I see option #3 was not clear.
public class Room
{
public virtual int Id { get; set; }
public virtual string UniqueID { get; set; }
public virtual int RoomID { get; set; }
public virtual float Area { get; set; }
public static Room Create(int roomId, int area)
{
Room room = new Room();
room.UniqueID = Guid.NewGuid().ToString();
room.RoomID = roomId;
room.Area = area;
return room;
}
}
IMHO, good idea is to make base class - abstract and its constructor - protected.
Next, inherited classes have their constructor private and - for outer world - uniform static method like "Instance", which first of all, initializes the constructor, then - calls whole set of class methods in correct sequence and finally - returns the instance of the class.

Categories

Resources