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);
}
}
Related
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
I have a class named Class1 and In this class I have a property named MyProperty. In another class I declare Class1 property but I want in this situation MyProperty be readonly. How can I do this?
public class Class1
{
public int MyProperty { get; set; }
}
public class Class2
{
public Class1 Class1Property { get; }
}
public class Class3
{
void Method()
{
Class2 obj = new Class2();
obj.Class1Property.MyProperty = 2;//I want this be illegal (In this place only)
}
}
Do some further abstraction and create an interface for Class1:
public interface IClass1
{
int MyProperty { get; }
}
Then make Class1 implement this interface:
public class Class1 : IClass1
{
public int MyProperty { get; set; }
}
Class2 should not expose a Class1 instance, but an instance of IClass1:
public class Class2
{
public IClass1 Class1Property { get; }
}
Now you got the behaviour you want:
public class Class3
{
void Method()
{
Class2 obj = new Class2();
obj.Class1Property.MyProperty = 2; // Doesn't work.
}
}
Class1 has decided that MyProperty is modifiable, no matter how you obtain a Class1, so what you want simply is not possible.
There are some ways that you can re-work your design, though. This is the approach I would take:
public class ReadOnlyClass1
{
public int MyProperty { get; protected set; }
}
public class Class1 : ReadOnlyClass1
{
public new int MyProperty {
get { return base.MyProperty; }
set { base.MyProperty = value; }
}
}
Now, you can give Class3 a property of type ReadOnlyClass1.
There are a couple ways to do this, the easiest as mentioned in the comments is by making the setter of "MyProperty" private:
public int MyProperty { get; private set; }
You can also try another access modifier that better suits your need.
Just think what the get and set mean: When being compiled, a Getter and Setter method gets created much like it was implemented in java.
You can also create the property with just a "get" and implement the "set" functionality outside of the property itself (like in the class constructor, in an internal method or something like that).
public int myProperty{get;private set;}//this is read only property
obj.Class1Property.MyProperty = 2;//this is illegal
I have a abstract class 'Building':
public abstract class Building {
abstract public int ID {get;}
abstract public string name {get;}
}
the class (for example) Headquarter : Building has the Variables for these getter and setter methods. The Problem is I have to write in every Subclass
private int _ID = 1;
public int ID {
get {return _ID;}
}
Is there a way to create for example one getter setter method like ahead, in the abstract class and save the code, so that I only have to set the variables?
Thanks for helping.
Instead of making the properties abstract, you could make the setter protected, and/or allow them to be set in the constructor:
public abstract class Building
{
// Optional constructor
protected Building(int id, string name)
{
this.ID = id;
this.Name = name;
}
public int ID { get; protected set; }
public string Name { get; protected set; }
}
This moves the implementation into the base class, but still only allows the subclasses to set those values.
You can try adding a protected setter in base class and set the value in ctor of derived classes:
public class Building
{
public int Id{get;protected set;}
and in derived class:
public class Headquarter: Building
{
public Headquarter()
{
Id = 1;
}
}
I'm having an hard time trying to bind an attribute within a DetailsView EditTemplateField. Here goes my data structure:
Class1{
public int idClass { get; set; }
public Class2 classObject { get; set; }
}
Class2 {
public int idClass2 { get; set;}
}
The Class1 is the ObjectDataSource DataObjectTypeName associated to the dropdownlist.
I'm trying to bind a Dropdownlist Value to the idClass2 like this:
Bind("classObject.idClass2");
You can't. AFAIK you can only use Eval (one way binding) with nested objects. Anyway what you can do is to modify the first class with a new property:
Class1{
public int idClass { get; set; }
public Class2 classObject { get; set; }
public int idClass2 {
get { return classObject.idClass2; }
set { classObject.idClass2 = value; }
}
}
and bind it: Bind(idClass2)
Is it absolutely necessary to have the idClass2 in a separate class? if this is the only property in Class2, why dont you just add the property to the Class1?
Even though you
Otherwise I think you need to extract the object Class2 and then bind it like this
var _classObject = class1.classObject;
Bind("_classObject.idClass2");
You can make a "plain" object
Class1{
public Class2 class2 { get; set; }
public int Var { get; set; }
public int InnerVar { get { return class2.Var; } }
}
Class2{
public int Var { get; set; }
}
Then you can use the Class1 InnerVar to access to Var in Class2.
when you make an object of classObject you should also make objects of all the classes that are lying in it. in this way you can access classObject.idClass2 , if you dont make object of idClass2 you'll get Null Exception.
I have two functions that do the basically same thing on two different classes.... each class has different properties.
For example:
public class ClassA
{
public int ColorID {get;set;}
public string ColorDescription {get;set;}
}
public class ClassB
{
public int TypeID {get;set;}
public string TypeDescription {get;set;}
}
public void ExFunctionSaveA(ClassA aClass)
{
aClass.ColorID=1;
aClass.ColorDescription="My Color";
Save();
}
public void ExFunctionSaveB(ClassB bClass)
{
bClass.TypeID=2;
bClass.TypeDescription="My Type";
Save();
}
As you can see the classes and the functions have the same type structure, just the property names are different... but I feel like I am repeating code doing this
Is there a way to make ExFunctionA and ExFunctionB into one function, so that I could use this for all classes that have similar structure
I know I could do some sort of generic thing like
public void ExFunctionSave<T>() // T is either ClassA or ClassB
{
.
.
.
.
Save();
}
but how would I handle the properties of each
Rather than using a generic, why not use inheritance to solve this?
public class theBase
{
string ID;
string Description;
}
public class theColor : theBase
{
}
public class theType : theBase
{
}
public void ExFunctionSaveA(theBase base)
{
base.ID=1;
base.Description="My Color";
Save();
}
If you can alter the definitions of your classes, then the best approach would be to make them implement a common interface that contains the properties you want to access:
public interface IDescribable
{
int ID { get; set; }
string Description { get; set; }
}
public class ClassA
{
public int ID { get; set; }
public string Description { get; set; }
public int ColorID
{
get { return ID; }
set { ID = value; }
}
public string ColorDescription
{
get { return Description; }
set { Description = value; }
}
}
public class ClassB
{
public int ID { get; set; }
public string Description { get; set; }
public int TypeID
{
get { return ID; }
set { ID = value; }
}
public string TypeDescription
{
get { return Description; }
set { Description = value; }
}
}
public void ExFunctionSave(IDescribable d, int id, string desc)
{
d.ID = id;
d.Description = desc;
Save();
}
Nothing more you can do unless the the 2 classes implement the same interface which has the function. In your case, even the function signatures are different.
You could define an Interface with attributes id and description.
The clases that has this structure could implement that interface.
And your method receive as parameter the interface and execute the moethods ...
Take a look at Reflection.
Reflection will let your code receive a ClassA, and discover that it has a ColourID and a ColorDescription. Likewise, when you receive a ClassB, you can discover its TypeID and TypeDescription. It's cool.
I would probably recommend a common interface, at least for your example, but if you're trying to something more complex and more generic, Reflection is the way to go.