Simple question: does an abstract property create a private backing field? Example:
public abstract Name { get; set; }
Will this create a private backing field? I want to force any class that derives this property to use their own backing field, not one that's created by the compiler.
No it doesn't. I just tested with the following class:
public abstract class Class1
{
public abstract string TestStringAbstract { get; set; }
public string TestString { get; set; }
}
and decompiled it in Reflector. This was the generated code:
public abstract class Class1
{
// Fields
[CompilerGenerated]
private string <TestString>k__BackingField;
// Methods
protected Class1()
{
}
// Properties
public string TestString
{
[CompilerGenerated]
get
{
return this.<TestString>k__BackingField;
}
[CompilerGenerated]
set
{
this.<TestString>k__BackingField = value;
}
}
public abstract string TestStringAbstract { get; set; }
}
As you can see only a single backing field was generated for the concrete property. The abstract one was left as a definition.
This makes logical sense since the property must be overridden by any child class there is no point in creating a backing field that there would be no way of ever accessing (since you can't ever access the abstract property).
On the other hand a virtual property will create a backing field and any class that overrides the property with an auto-implemented replacement will create its own backing field at that class's level.
No. Since it's abstract, the class implementer must implement the property. If the implementer declares it that way, then Yes, it's an automatic property with a hidden member to hold the actual value.
There's a difference between:
public abstract string Name { get; set; }
and
public string Name { get; set; }
The first property declaration doesn't create a backing field. It just creates an abstract property (kind of like an interface method declaration), which has to be implemented by any non-abstract inheriting class.
The second declaration is an auto-property, which DOES create a backing field. It's actually compiler syntactic sugar shorthand for:
private string _name;
public string Name { get { return _name; } set { _name = value; } }
Related
I created classes that derive from a parent class looking like this.
class Usability
{
public string useName = "404";
}
and
class Heal : Usability
{
public string useName = "drink";
}
when putting multiple in a Dictionary
public Dictionary<int, Usability> useDict = new();
and then accessing useName via
foreach(var usability in item.usabilitys)
{
Console.Write(usability.useName);
}
allways prints "404". When using
foreach(Heal usability in item.usabilitys)
{
Console.Write(usability.useName);
}
instead prints "drink". There are functions and more data included in sub classes but this breaks down the problem as much as possible.
useName is the field, and fields can't be inherited.
You can use the properties instead of the fields:
public class Base
{
public virtual string Name { get; } = "404";
}
public class Inheritor : Base
{
public override string Name { get; } = "drink";
}
You must mark the base property as a virtual to override it in the class Inheritor.
Properties is just syntax sugar to getter and setter methods, so the property Name is really compiled to the method get_Name.
When you mark the property as the virtual you really make virtual method get_Name and you can override it.
If I declare Auto-Implemented properties in C# classes, then public string Property { get; set; } becomes:
private string _property;
public string get_Property() {
return _property;
}
public void set_Property(string value) {
_property = value;
}
which includes a private field string _property.
If I create an interface, I am allowed to use Auto-Implemented properties like so:
string Property { get; set; }
Why can I declare Auto-Implemented properties inside Interface, but I can't use the longer, more verbose syntax that declares private fields? I am aware of the definition that says:
An interface contains only the signatures of methods, properties, events or indexers
Is the private field in interfaces not generated the same as in classes? Is it generated at all?
Why can I declare Auto-Implemented properties inside Interface
They aren't auto-implemented, it's just that the syntax of a property declaration is identical to the syntax for an auto-implemented property definition.
This:
interface IFoo
{
String Bar { get; set; }
}
Means: "IFoo has a public[1] String property named Bar which has a getter and a setter."
This:
class Foo
{
String Bar { get; set; }
}
Means: "Foo has a private[2] String property named Bar which has a getter and a setter, and the getter and setter are both auto-generated by the compiler and operate on a hidden instance field.
Note that the syntax used in the interface is unrelated to the syntax used by implementation in the class or struct. So given the same IFoo as above...
interface IFoo
{
String Bar { get; set; }
}
...we can have:
// Using auto-implemented property:
class Foo2 : IFoo
{
public String Bar { get; set; }
}
// Using explicit backing field:
class Foo3 : IFoo
{
private String bar;
public String Bar
{
get { return this.bar; }
set { this.bar = value; }
}
}
// Using expression-body syntax with a backing field:
class Foo4 : IFoo
{
private String bar;
public String Bar
{
get => this.bar;
set => this.bar = value;
}
}
// Using explicit interface implementation with a backing field:
class Foo5 : IFoo
{
private String bar;
String IFoo.Bar
{
get { return this.bar; }
set { this.bar = value; }
}
}
// You can also use explicit interface implementation with an auto-implemented property:
class Foo6 : IFoo
{
String IFoo.Bar { get; set; }
}
// However, if it's a getter-only property you won't be able to set a property value in the constructor - but you can initialize it inline:
interface IReadOnlyFoo
{
String Bar { get; }
}
class Foo7 : IReadOnlyFoo
{
String IReadOnlyFoo.Bar { get; } = "foo"; // ok
}
class Foo8 : IReadOnlyFoo
{
public Foo8()
{
this.Bar = "foo"; // <-- Error. `Bar` is not a member of `this`.
// You also can't cast `(IReadOnlyFoo)this` because `IReadOnlyFoo` does not contain a setter.
}
String IReadOnlyFoo.Bar { get; }
}
Is the private field in interfaces not generated the same as in classes
Interfaces don't have fields, interfaces only have virtual methods (or rather: an interface can be thought-of as a single vtable). Note that internally: properties and events are also fundamentally virtual methods (also note that while internally they're virtual calls, implemented interface methods are not automatically virtual (in the C# sense) in that a subclass of an interface implementation cannot arbitrarily override any interface member[3].
Also not to be confused with "Default interface implementations" in C# 8.0 which a more akin to extension methods than treating interfaces as classes, because interfaces still cannot have fields.
You should also familarise yourself with C#'s expression-bodied member syntax (though it isn't used much for property-setters):
class Foo2
{
String bar; // this is a private instance field
String Bar // this is a private instance property
{
get => this.bar;
set => this.bar = value;
}
}
[1] Disregarding Explicit Interface Implementation, of course.
[2] Class members are private by default if they don't have an explicit access-modifier.
[3] Subclasses can reimplement an interface which will have the effect of overriding any virtual-calls to that interface member, but only if the member is accessed through an interface reference rather than through an object reference to the class's supertype.
I'm studying this simple class and wondering what difference the private set of the Name property actually makes?
If that line simply read public string Name { get; } how would the user's interaction with the class change?
public class Contact2
{
// Read-only properties.
public string Name { get; private set; }
public string Address { get; }
// Private constructor.
private Contact2(string contactName, string contactAddress)
{
Name = contactName;
Address = contactAddress;
}
// Public factory method.
public static Contact2 CreateContact(string name, string address)
{
return new Contact2(name, address);
}
}
They are both read-only properties, and objects of this class can only be constructed via the static method, so does it matter if the set of name is private or not?
EDIT
It is part of this MSDN code:
https://msdn.microsoft.com/en-us/library/bb383979.aspx
In C# 6:
public string Name { get; private set; }
Can be set from any method within the class.
public string Address { get; }
Is a read-only property and can only (and must) be set on initialization.
In your code they're functioning the same way, however the read-only property enforces an additional constraint making the property immutable as it can only be set once, whereas you could add a method to the class which mutates Name making the class mutable.
Getter-only auto properties like public string Name { get; } were not allowed before C# 6.0, so the code would not compile. That's why you needed a private setter before.
See: Getter-only auto-properties.
Consider the following interface
public interface ICustomData
{
String CustomData { set; get; }
}
According to MSDN documentation, interfaces members are automatically public.
Lets say I now want to implement my interface:
public class CustomDataHandler : ICustomData
{
}
This would break at compile time, telling me that I have not implemented "CustomData"
This on the otherhand would work:
public class CustomDataHandler : ICustomData
{
public String CustomData { set; get; }
}
My question is: If the member of the interface is automatically public, why MUST I declare the implementation in the class? If the interface declaration is syntactically identical to the class declaration, why can the compiler not infer this automatically from my interface?
EDIT:
My reason for asking. Imagine a scenario where you are building data models, entities etc. I might code some interfaces to these models like so:
public interface IUserAccount
{
Guid Identity { set; get; }
String FirstName { set; get; }
String LastName { set; get; }
String EmailAddress { set; get; }
String Password { set; get; }
}
public interface IUserDataEntry
{
Guid DataIdentity { set; get; }
String DataName { set; get; }
String Data { set; get; }
}
It would be far simpler to construct the models like so:
public class UserAccount : IUserAccount
{
}
public class UserDataEntry : IUserDataEntry
{
}
public class Combined : IUserAccount, IUserDataEntry
{
}
An interface is not there to provide an implementation, it is there to define a contract. This then allows for different implementations to be built which implement it.
They may be syntactically identical, but they mean different things (i.e. they are not semantically identical).
In the interface, the syntax means that an implementing class must expose such a property, with get and set accessors implemented as it sees fit (either explicitly or implicitly). An interface merely defines the outward behaviour that a class must provide; it does not provide any implementation of that behaviour.
In the class, the syntax is an "auto-property", an implementation of the property defined by the interface, and the get and set accessors are implicitly converted into full implementations with a backing field. It looks something like this when it's compiled:
public class CustomDataHandler : ICustomData
{
private string customData;
public string CustomData
{
get
{
return customData;
}
set
{
customData = value;
}
}
}
You are implicitly implementing the interface. In this instance the method signatures of the class must match those of the interface (including accessibility). Ensuring that the methods are marked as public ensures that there are no surprises when looking at the class, for instance:
public class CustomDataHandler : ICustomData
{
String CustomData {get; set}
String PrivateCustomData {get;set;}
}
Even though both properties are declared the same, the CustomData property would be public by virtue of it being declared on the interface even though the declaration looks identical to that of PrivateCustomData. This would be inconsistent and lead to harder to maintain code.
If you do not wish to set the access modifier, you could explicitly implement the interface:
public class CustomDataHandler : ICustomData
{
String ICustomData.CustomData { set; get; }
}
The interface declaration is only specifying the behaviour which the interface defines. In your case, this is a property called CustomData which has a get and set (it is a read/write property) which is of type string.
The class which implements the interface needs to do exactly that - to specify the implementation.
Now in your case, you are using auto implemented properties { get; set; } which looks the same as the interface declaration, however you could also have a backing field and behaviour in your get or set methods.
Here's an example where the CustomData property is private in a derived class:
public class CustomDataHandler : ICustomData
{
private string CustomData { set; get; }
string ICustomData.CustomData { get; set; }
}
But this code compiles, because there is also an explicit implementation of the property.
So, the public modifier is not redundant in this case.
You must explicitly implement it because... You are not limited to implementing it that way. You could use a field, or do something else in your method. An interface is only a method contract that guaranty that this method exist.
public class CustomDataHandler : ICustomData
{
public String CustomData
{
get { return "None of your business!"; }
set { } // Decide to do nothing
}
}
The interface only guaranty this method will exist. Not what you're gonna do with it.
EDIT: As for your edit of your question, you probably seek to have a parent class instead of an interface if you want to implement the method only once for a collection of classes. However, while you can combine interface, you cannot combine parent classes. But, you can add interface at different point of a classes hierarchy.
I have used and learned only virtual methods of the base class without any knowledge of virtual properties used as
class A
{
public virtual ICollection<B> prop{get;set;}
}
Could someone tell me what that means ?
public virtual ICollection<B> Prop { get; set; }
Translates almost directly to:
private ICollection<B> m_Prop;
public virtual ICollection<B> get_Prop()
{
return m_Prop;
}
public virtual void set_Prop(ICollection<B> value)
{
m_Prop = value;
}
Thus, the virtual keyword allows you to override the property in sub-classes just as you would the above get/set methods:
public override ICollection<B> Prop
{
get { return null; }
set { }
}
In object-oriented programming, a virtual property is a property whose behavior can be overridden within an inheriting class. This concept is an important part of the polymorphism portion of object-oriented programming (OOP).
look at the example below:
public class BaseClass
{
public int Id { get; set; }
public virtual string Name { get; set; }
}
public class DerivedClass : BaseClass
{
public override string Name
{
get
{
return base.Name;
}
set
{
base.Name = "test";
}
}
}
at the presentation level:
DerivedClass instance = new DerivedClass() { Id = 2, Name = "behnoud" };
Console.WriteLine(instance.Name);
Console.ReadKey();
the output will be "test", and not "behnoud", because the "Name" property has been overridden in the derived class(sub class).
In Entity Framework (which I believe your example refers to), your POCO classes are created and wrapped into a proxy class. Proxy class is a descendant of the class that you declare, so your class A becomes a base class. This proxy class is populated with data and returned back to you. This is necessary in order to track changes. Have a look at this article http://technet.microsoft.com/en-us/query/dd456848
I had a similar problem in trying to understand this and after a few debugging sessions and seeing the proxy classes and reading about tracking changes it made be figure out why it is declared the way it is.
Properties are actually specials cases of Getter and Setter methods. So they are like combinations of Getter and Setter methods as shown below:
private string _name;
public string GetName()
{
return _name;
}
public void SetName(string value)
{
this._name = value;
}
So virtual keyword is same for properties as well which means it is overrideable by the child classes and initial implementation can be changed.
Properties are a shortened form of accessor methods (Get & Set). That means that the virtual keyword has the same meaning as with any other method. That means you can override it in derived classes.
You can have methods (often), properties, indexers or events, the virtual keyword has the same meaning : modifying the meaning (override) of the base class item.
With properties, you can change the get/set accessors.
It's a collection that's implementation can vary in a descendant class.