I want have readonly property in a Data Transfer Object,DTO object, without set; accessor like:
public class ViewBannerDTO
{
public int Id { get; }
}
but why get:
'ViewBannerDTO.Id.get' must declare a body because it is not marked abstract or extern. Automatically implemented properties must define both get and set accessors.
and also why i cant:
public readonly int Id{get;}
You can't have no setter for an auto-implemented property (otherwise how would you set it?). You can either add a getter implementation (and a backing field if necessary) or use a private setter:
public class ViewBannerDTO
{
public int Id { get; private set; }
}
Why i cant I do:
public readonly int Id{get;}
because readonly only applies to fields. You can accomplish the same thing with a property by using a readonly backing field and no set accessor:
private readonly int _Id;
public int Id {get { return _Id; } }
but you can't have a readonly auto-implement property because there's no syntax to initialize a property without a set accessor.
It is exactly what is sais: There is not set accessor for that variable and you have no Get method implemented which can do stuff to get you a value.
Either go:
public int Id { get; set; }
OR
public int Id
{
get
{
int something = GetStuffDone();
return something;
}
}
Another something you can do is make the set function private like this:
public int Id { get; private set; }
And an answer to why you cant: The value will never be set cause it has no accessor.
This is just a repeat of answers but OP does not understand
public class ViewBannerDTO
{
public int Id { get; private set; }
public ViewBannerDTO ()
{
Id = 12; // inside the class can assign private
// private not seen outside the classs
}
}
or you could
public class ViewBannerDTO
{
private int id = 12;
public int Id { get { return id; } }
}
or you could
public class ViewBannerDTO
{
public int Id { get { return 12; }
}
As of C# 9 you can get read-only behavior by using an init accessor. Example:
public class Foo
{
public int Bar { get; init;} = 1
public int Baz { get; private init;} = 2
}
var foo = new Foo { Baz = 3};
In both cases the property can only be set during object construction. The private keyword ensures only the class can set the value, otherwise the caller of new can set the value with the object literal notation in the example.
reference: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/init
Related
I want ask you, how should i set and get properties values? Should i do this, for example directly from another class and set property as public property or maby better practise is to set property as private and change it or get it by using public function implemented in this class?
first case:
//Class.cs
public class Class
{
public int Number{ get; set; }
}
//AnotherClass.cs
public class AnotherClass
{
Class class = new Class();
class.Number = 2;
int number = class.Number;
}
Second case:
//Class.cs
public class Class
{
private int Number{ get; set; }
public void setNumber(int number)
{
Number = number;
}
public int getNumber()
{
return Number;
}
}
//AnotherClass.cs
public class AnotherClass
{
Class class = new Class();
class.setNumber(2);
int number = class.getNumber();
}
this code is obviously a bit simplified ...
I would do that:
//Class.cs
public class Class
{
public int Number { get; set; }
}
//AnotherClass.cs
public class AnotherClass
{
Class class = new Class
{
Number = 2 // use , (comma) to separate if needed when
// the class has other fields
};
int number = class.Number;
}
What does private access modifier for init only setter in C# mean? I usually make setter as private for most of the properties in my domain classes. With init, does it matter?
The following seem to work without any problem, the compiler does not complain.
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
So how is the above different from the below. There is not private below.
public class Point
{
public int X { get; init; }
public int Y { get; init; }
}
It affects where the setter can be called from, just like normal setters.
Consider this code:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
}
class Program
{
static void Main()
{
var point = new Point { X = 10, Y = 20 };
}
}
That fails with two compile-time errors:
The property or indexer 'Point.X' cannot be used in this context because the set accessor is inaccessible
(and the equivalent for Y).
The same initializer would be valid in the Point class, because the set accessors are accessible there. For example, you might want to use a public factory method, which is implemented with an object initializer:
public class Point
{
public int X { get; private init; }
public int Y { get; private init; }
public static Point FromXY(int x, int y) =>
new Point { X = x, Y = y };
}
(There are various reasons why that might not be ideal, or you might prefer to add parameters to a private constructor, but it's an example of where the private init-only setters are accessible.)
Likewise the code above would be valid without the private part of the set accessors, because then they can be called from anywhere (as part of an object initializer).
The init keyword was added in c# 9.0 in order to add immutable properties on objects.
The problem we used to have is that if you have this object you could still modify the Name property (although it has a private setter) via a public method. for example:
public class Person
{
public Person(string name)
{
this.Name = name;
}
public void SetName(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
And we also couldn't use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile Error
};
Now, if we change the code to use init
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; init; }
}
We are now able to use object initializers
var person = new Person
{
Name = "Jane Doe" // No error
};
But, if we use your private init like your example
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; private init; }
}
We won't be able to use object initializers
var person = new Person
{
Name = "Jane Doe" // Compile error
};
I have a C# class with properties in which I end up using this class a a collection of type List in another class.
What I want to do is just always set the Type property to be of value "3"
Should /Can this be done with the getter/setter or should I use the System.Component.DefaultValue .... attribute
public class ReportDefinition
{
public int Id { get; set; }
public string ReportGroupNameDef { get; set; }
public int SortOrder { get; set; }
public int ReportGroupId { get; set; }
[System.ComponentModel.DefaultValue(3)]
public int Type { get; set; }
}
I think that I would prefer not using this way [System.ComponentModel.DefaultValue(3)]
You could use a read-only property, and either return the value of a private field, or just return the value you want right in the get.
public class ReportDefinition
{
private int m_type = 3;
public int Type
{
get
{
return m_type;
}
}
}
I don't expect to get or steal away the existing selected answer but I did want to help clarify a bit of the comments that I am reading.
Yes indeed best clean way is auto-property public int Type { get; } = 3; -- Caveat is C# 6
Another C# 6 without auto-property would be an expression body
private int m_type = 3;
public int Type => m_type;
However If you are stuck with wanting to use Linqpad 4 then the selected answer is "fine"
private int m_type = 3;
public int Type
{
get
{
return m_type;
}
}
I've tried to learn the short version of get & set in C#, but I don't know how to use them.
This is what I tried:
namespace SomeNamespace {
class SomeClass {
private int field1 { get; set;}
private int field2 { public get; public set; }
}
class OtherClass {
SomeClass sc = new SomeClass();
int field1 = sc.field1; //it doesn't work
int field2 = sc.field2; //it also doesn't work
sc.field1 = 1; //same here
sc.field2 = 2; //and here
}
}
In my SomeClass object I don't have access to any field nor "special" method to do this.
I obviously don't get it, so please help me to understand.
You need to use the accessors the other way around on your properties if you want to only allow read access on your property from outside classes:
public int field2 { get; private set; }
// setting only allowed from SomeClass, not from OtherClass or inheritors
To allow inheritors, you need to set private to protected.
If you want to allow both read and write from outside classes:
public int field2 { get; set; }
// setting allowed from any class
You need to declare them as public. Like following.
namespace SomeNamespace {
class SomeClass {
public int field1 { get; set;}
public int field2 { get; set;}
}
class OtherClass {
SomeClass sc = new SomeClass();
// frist set the values
sc.field1 = 1;
sc.field2 = 2;
// then read them
int field1 = sc.field1;
int field2 = sc.field2;
}
}
In C# 3.0 and later, auto-implemented properties make
property-declaration more concise when no additional logic is required
in the property accessors. They also enable client code to create
objects. When you declare a property as shown in the following
example, the compiler creates a private, anonymous backing field that
can only be accessed through the property's get and set accessors.
There are advantage of having getter/setter ( in comparison to just public variables).
Set accessibility via private set; etc..
You can add validation while setting the value or format while getting the value.
You can use them as part of an interface definition or an abstract class.
SOUREC - http://msdn.microsoft.com/en-us/library/bb384054.aspx
public class SomeClass
{
//Will be accessible by instance of this class
public int Field1 { get; set; }
//Accessible within class methods only
private int Field2 { get; set; }
public void SomeMethod()
{
//You can use private property in any of method within class only
Console.WriteLine(Field2);
}
//Accessible from derived class
protected int Field3 { get; set; }
}
public class SomeDerived : SomeClass
{
public void SomeDerivedFunction()
{
//Accessing baseclass Property
Console.WriteLine(Field3);
}
}
public class SomeThirdPartyClass
{
private SomeClass sc;
public SomeThirdPartyClass()
{
sc = new SomeClass();
//Field one as public accessible in other classes by instance
Console.WriteLine(sc.Field1);
}
}
I try to use AIP
public int AIP_NoSet
{
get { ;}
}
Compiler say that it is an error:
Program.c1.AIP_NoSet.get': not all code paths return a value
But even if I write
public int AIP_NoSet
{
get { ;}
set { ;}
}
it shows me the same error.
Where am I wrong?
You should write
public int AIP { get; set; }
when you write { ;} after it, this is seen as a syntacticaly incorrect attempt of a user implemented property. You can't have no setter, but you can make the setter private:
public int AIP_PrivateSet { get; private set; }
A moment of derp.
public int AIP_NoSet { get; set; }
Sounds like you want an automatic property with only a 'get' defined.
This is not allowed by the compiler.
You can accomplish this by adding a private set (as others have answered), or by not using an automatic property:
private int _aip = int.MaxValue;
public int AIP_NoSet { get {return _aip;}}
Or, if you NEVER want to set it, just use a const:
public const int AIP_NoSet = 2;
Make setter access private and fix syntax.
public int AIP_NoSet { get; private set; }