Let's say I have a POCO with a property as such
public class Person
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
// DO STUFF;
}
}
}
When the object is being initialized by EF, I only want _firstName to be set and nothing else, only after the object is initialized do I want a set to run the rest // DO STUFF;.
Why don't you simply
Declare the property setter as protected; and
Expose your // DO STUFF behavior as a proper method SetFirstName(string firstName)?
Something like this:
public class Person
{
public string FirstName { get; protected set; }
public string SetFirstName(string value)
{
_firstName = value;
// DO STUFF;
}
}
Much cleaner, don't need to "hack" EF at all.
Related
I was wondering if there is a way to set a default function for a getter or a setter.
For example, let's say I have this:
public class MyClass
{
public bool IsDirty {get; private set; } = false;
private string _property;
public string Property1
{
get
{
return _property1;
}
set
{
if (value != _property1)
{
_property1 = value;
IsDirty = true;
}
}
}
}
I was wondering if there was a way to do something like this:
public class MyClass
{
public bool IsDirty {get; private set;} = false;
MyClass.defaultSet = { if (value != !_property1) { _property1 = value; IsDirty = true; } };
private string _property1;
public string Property1 { get; set; }
public string Property2 {get; set;}
public string Property3 {get; set;}
//...
}
So that I don't have to do it the first way on this big class I have (~100 properties).
You can reduce the noise by using a helper method like this
private void Set<T>(ref T field, T value)
{
if (!Equals(value, field))
{
field = value;
IsDirty = true;
}
}
Then you can write:
public string Property1
{
get => _property1;
set => Set(ref _property1, value);
}
No, this doesn't exist, for several reasons:
Not every property is going to be a string, so this would need to correctly handle integers, DateTimes, Decimal, etc
Primitive value types are bad enough, but then start throwing in things like Tuples, complex classes (where changing a class member is still get operation on the property itself!), delegates, etc
If you reference a property by it's own name, you're creating a circular reference that will cause a StackOverflowException.
Not every property is going to use the same Property name, so that part of the method is different. You'd need another keyword or argument to the set method.
You need a way to exempt the someBool / IsDirty property.
how can i create a method that get's an object to read only purpose
public class Person
{
public string Name;
}
public void RunMe(Person p)
{
p.Name="XXXX";
}
var p =new Person();
p.Name="YYYY";
RunMe(p);
Console.WriteLine(p.Name);
I am getting XXXX. but i want that the person object will not change it value.
you can use interfaces to restrict the access. It is also better to pass interfaces instead of concrete objects as parameters to methods.
public interface IReadablePerson
{
string Name { get; }
}
public interface IWritablePerson
{
string Name { set; }
}
public class Person : IReadablePerson, IWritablePerson
{
public string Name { get; set; }
}
and then have a method like this
public void RunMe(IReadablePerson p)
{
p.Name = "XXXX"; //compile time error!!!
}
The way to do this is via the get and set accessors, just don't define a set:
public String Name { get; }
This will make a property that you can treat exactly like a normal field for your purposes. Underneath properties are a little more complex using methods to set a backing field which you can read about on msdn
If you need to be able to set the property just once then define the set as private and pass the parameter into the constructor:
public class Person
{
public Person(String name)
{
this.Name = name;
}
public String Name { get; private set; }
}
Classes in C# are reference types, so there's no way to do what you want to do if Person is a class.
You could make it a value type (by making it a struct) in which case, a copy of the object would be passed in, but that may take implications at some other points in your program, so be wary if you do it.
It seems that you want to somehow be able to lock the member. One option would be to make the "set" dependent on another member like this:
public class Name
{
public bool Locked { get; set; }
private string name;
public string Name
{
get { return this.name; }
set
{
if(!this.Locked)
this.name = val;
}
}
}
Edit: Alternate method for making lock permanent.
public class Person
{
private bool locked = false;
public void Lock()
{
this.locked = true;
}
public bool Locked
{
get { return this.locked; }
}
// add same Name member as above
}
Edit: Yet ANOTHER way to lock, using a key.
private object key = null;
public bool Locked
{ get { return this.key != null; } }
public void Lock(object obj)
{
if (this.key == null)
{
this.key = obj;
}
}
public void Unlock(object obj)
{
if (this.key == obj)
{
this.key = null;
}
}
You can throw an exception if you want if trying to unlock with the wrong key object.
The behaviour described after the first setting of the property is this:
private string _name;
public string Name
{
get { return _name; }
set { // no setting }
}
This is NOT A GOOD PRACTICE.
you create unexpected behaviour for properties (if this is a public class).
Any consuming assembly cannot view the body of the get and set methods would expect a set method to behave a sertain way (setting a value).
This kind of behaviour should be put in a seperate set method.
This way you can see if it changed, throw an exception if you want, or return true if it changed.
Then you can still use the property for getting the value.
private bool _locked;
public string Name { get; private set;}
public boolSetName(string value)
{
bool hasChanged = false;
if(!_locked)
{
Name = value;
_locked = true;
hasChanged = true;
}
return hasChanged
}
I have an object model that has a property like this:
public class SomeModel
{
public string SomeString { get; set; }
public void DoSomeWork()
{
....
}
}
I want the DoSomeWork function to execute automatically after the SomeString property changes. I tried this but it's not working:
public string SomeString { get; set { DoSomeWork(); } }
What's the correct syntax?
Use a private field instead, like this ...
public class SomeModel
{
private string someString = "";
public string SomeString {
get { return this.someString; }
set {
this.someString = value;
this.DoSomeWork();
}
}
public void DoSomeWork()
{
....
}
}
You can't do this with automatic properties - you'll have to create a "manual" property backed by a field.
private string _someString;
public string SomeString
{
get { return _someString; }
set
{
_someString = value;
DoSomeWork();
}
}
If you really can't deal with this boilerplate (say you'd have to do this hundreds of times), consider using an AOP framework like PostSharp to implement this on your behalf - you'd just need to declare an automatic property and an attribute to get the binary rewriter to implement the desired scheme.
This will work...
private string _someString;
public string SomeString { get { return _someString; } set { _someString = value; DoSomeWork(); } }
private string _someString;
public string SomeString
{
get
{
return _someString;
}
set
{
DoSomeWork();
_someString = value;
}
}
C# team has introduced the auto-implement properties in C# 3.0. with the logic of minimizing the model making which is backed by an anonymous field created by compiler. this one is used when you don't need to implement any additional logic on a property of an object class. so it just followed as.
public string Name{ get; set;}// auto-implemented property. no additional logic.
if we want to add some logic as you want to add one function. we must be writing a manual property backed by a private field as like below.
private string _Name;
public string Name
{
get {return _Name;}
set {
_Name=value;
DoSomething(); //Additional logic implemented.
}
}
im tring to return an BL object from wcf server
but i get all the private proprties only.
how to return only the BL public properties.
thats the BL Class in some dll i refernce to wcf server
[Serializable()]
public class Account
{
#region properties
private int _accountId;
public int AccountID
{
get
{
return _accountId;
}
set
{
_accountId = value;
}
}
private string _title;
public string Title
{
get
{
return _title;
}
set
{
_title= value;
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name= value;
}
}}
thats the wcf method in the interface
[OperationContract]
[WebGet(UriTemplate = "{Key}/{Client}/Registrations?eventID={eventID}®Status={regStatus}")]
List<Registration> GetRegistrations(string key, string client, int eventID, int regStatus);
the method that make the return list:
public List<Registration> GetRegistrations(string key, string client, int eventID, int regStatus)
{
if (Validation.ValidateClient(key, client) == false)
return null;
List<Registration> regs = Registration.GetRegByColumnandValue(eventID, (Registration.RegStatusFlags)regStatus);
return regs;
}
WCF does not use the [Serializable] attribute.
Write your BL object (or a DTO ) like this:
[DataContract]
public class Account
{
private int _accountId;
[DataMember]
public int AccountID
{
// get/set
}
private string _title;
[DataMember]
public string Title
{
// get/set
}
}
The [Serializable] is wrecking the way the type is serialized, it's not suitable for WCF.
If it is embedded in another layer and you cannot remove it, then create a DTO (Data Transfer Object) class. You'll need code to copy the relevant properties, at least server-side.
Would someone be able to explain or provide a link to a page that describes what Automatic Properties are (in relation to LINQ) in lamens terms please
Automatic properties - better call them "auto-implemented properties", are a new syntax sugar added in latest C# versions as some comment pointed out.
It consist in a property that declare its accessors without body and C# compiler creates the corresponding private fields for you:
public string Name
{
get;
set;
}
Note that this isn't an abstract member, becase it'd be marked with the appropiate attribute "abstract"!
Additionally to that, these accessors, as non-auto-implemented ones, can have visibility attributes: private, internal, public (default behavior):
public string Name
{
private get;
internal set;
}
Here is an automatic property in C# 3.0:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
compared to a non automatic property:
public class Person
{
string _FirstName;
string _LastName;
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
}
Here's the post by Dan Wahlin on automatic properties, from where I got the above code.
Refer to the following:
Auto-Implemented Properties
Using Automatic Properties in LINQ