Property with method? - c#

Maybe I am overlooking something obvious, but I have seen in code where you may have a property like "HairColor", and then a method like "HairColor.Update()". Is this possible?
Person person = new Person(int personID);
person.HairColor = "Blonde";
person.HairColor.Update();
I have specific properties that I want to be able to extend on a case by case basis. I guess I could have a method called "HairColorUpdate", but seems that HairColor.Update() should be possible. I don't want to use "set" because I don't always want to update the DB this way.
The reason I am doing this is because I may only want to call the database to update one column instead of calling my save method which updates every column hopefully improving efficiency.

person.HairColor.Update() just means that the type returned by the HairColor property has a method called Update. In your example it looks like HairColor is a string, so to achieve that you need to implement an extension method for string. E.g. something like
static class StringExtension
{
public static void Update(this string s)
{
// whatever
}
}
However, I don't see the point of doing this. The Update method is a static method that works on the string, so it doesn't affect the Person instance. (even if string did have an Update method it would be unrelated to the Person type).
I believe you would want to have the Update method on Person instead as others have pointed out.

That is not possible, unless the return value of HairColor has an Update() method. Another way to do this is to have
Person person = new Person(int personID);
person.HairColor = "Blonde";
person.Update();
Where the update method checks to see which fields have been updated and then updates the database based on that information.

HairColor would probably have to be a struct type to make what you want to work. Plus, you would have to do operator overloading. I'm not sure if this is truly the design path you want to pursue. If, for some perverse reason, you absolutely must do it, this is the kind of struct definition you would need (very roughly, LOL):
public struct HairColorStruct
{
private string m_hairColor;
public void Update()
{
// do whatever you need to do here...
}
// the very basic operator overloads that you would need...
public static implicit operator HairColorStruct(string color)
{
var result = new HairColorStruct();
result.m_hairColor = color;
return result;
}
public static explicit operator string(HairColorStruct hc)
{
return hc.m_hairColor;
}
public override string ToString()
{
return m_hairColor;
}
public static bool operator ==(HairColorStruct from, HairColorStruct to)
{
return from.m_hairColor == to.m_hairColor;
}
public static bool operator ==(HairColorStruct from, string to)
{
return from.m_hairColor == to;
}
public static bool operator !=(HairColorStruct from, HairColorStruct to)
{
return from.m_hairColor != to.m_hairColor;
}
public static bool operator !=(HairColorStruct from, string to)
{
return from.m_hairColor != to;
}
}
You can then redefine your Person object like this:
public class Person
{
public HairColorStruct HairColor { get; set; }
// whatever else goes here...
}
In your code, HairColor can be simply assigned whatever you desire as long as it's a string:
var person = new Person();
person.HairColor = "Blonde";
// this will emit "True" to the console...
if (person.HairColor == "Blonde")
{
Console.WriteLine(true);
}
else
{
Console.WriteLine(false);
}
// update the info per your logic...
person.HairColor.Update();
// you can change the hair color and update again, LOL
person.HairColor = "Brown";
person.HairColor.Update();

It's not a property with a method, but type returned by the property has that method declared inside. So you use a property and within returned value, which is the type, call the method.

I think you need Update method on the Person class, not Update method on string:
Person person = new Person(int personID);
person.HairColor = "Blonde";
// set other properties
person.Update();
Actually mixing business logic of person class and database-related logic is rarely good idea. So, I'd go to something like:
dbSession.SaveOrUpdate(person); // NHibernate
Or even extension method:
public static void Update(this Person person)
{
// connect to database and do update query
}

Couldn't you just do:
public class HairColor : String
{
private int _personID;
public HairColor(int personID)
{
_personID = personID;
}
public void Update()
{
//update the database here for hair color
}
}
This way you can have more control with specific functionality. Remember, class responsibility.
This solution is only if you really want to update one column of course.
Hope that helps.

Related

How to reset delegate to original code

given this delegate
public class XYZ
{
public static Action<Profile> DoSomething = (profile) =>
{
//some default code here
return;
};
}
at some time in my main execution I override it with this:
XYZ.DoSomething = (currProfile) =>
{
// some overriding code here
}
How do I set the code back to the original default code when I need to without duplicating code?
Here's a good reason to never use public fields...
Once you set it; its gone. You can hold onto the original value though:
var originalAction = XYZ.DoSomething;
XYZ.DoSomething = ...;
XYZ.DoSomething = originalAction;
Usually it is a bad idea to rely on client code to handle this however; so if I was writing it I would expose as a property like so:
public Action<X> DoSomethingOverride {get; set;}
public Action<X> DoSomething => doSomethingOverride ?? DefaultMethod;
private void DefaultMethod (X param)
{
}
There are a number of other ways to handle this, but all involve storing off the original method. All good ways to handle this will use a property to ensure that only the declaring class is actually setting the DoSomething method and that resetting to the default is possible.
Total aside; since this is static setting the action will affect everything that uses this class. This is asking for bugs later; don't do that.
Maybe somthing like this?
public static Action<Profile> _doSomethingBase = (profile) =>
{
//some default code here
return;
};
public static Action<Profile> _doSomething = _doSomethingBase;
public static Action<Profile> DoSomething
{
get => _doSomething;
set => _doSomething = value;
}
public static void RevertDoSomething()
{
DoSomething = _doSomethingBase;
}

C# - Good and flexible way to pass value types by reference?

My problem, narrowed down to a simple explaination, is the following:
I have a class which needs to work with a number (without changing it) which is subject to change. This number doesn't necessarily come from another class, and it can be anything.
But I'd like to only "give" it to the class once, instead of constantly having to call update methods or having to create a wrapper (since again, as I said, this should work with any kind of number and having to wrap up everything is kind of unpratical).
Here's some code, hoping it helps:
public class SimpleExample
{
int value;
public SimpleExample(int variableOfWhichINeedAReference)
{
//Of course this won't work, but I'll keep it simple.
value = variableOfWhichINeedAReference;
}
public void DisplayValue()
{
print(value);
}
}
public class RandomClass
{
int myValue = 10;
SimpleExample s = new SimpleExample(myValue);
public void WorkWithValue()
{
myValue++;
}
public void Display()
{
print(foo);
print(bar);
s.DisplayValue();
}
}
Now, the problem seems pretty obvious: If I instantiate a SimpleExample and give it a variable as a parameter, it will get its value rather than a reference to it.
Is there a simple enough way that can avoid me the creation of a wrapper? Thanks.
Make a really simple class:
class Ref<T>
{
public T Value;
public Ref<T>()
{
}
public Ref<T>(T value)
{
this.Value = value;
}
}
Then use it like this:
class A
{
Ref<int> x;
public A(Ref<int> x)
{
this.x = x;
}
public void Increment()
{
x.Value++;
}
}
...
Ref<int> x = new Ref<int>(7);
A a = new A(x);
a.Increment();
Debug.Assert(x.Value == 8);
Note that the Ref<T> class here is a reference to a value - not a reference to a variable. If you want a reference to a variable, use Eric Lippert's solution (as pointed out by Filip).
So what you want is not an int, but rather a way of getting an int at some point in time. There are several ways of doing this, one of which is to have your object accept a Func<int>. Then the code can pass in a method that returns the current value of...whatever, rather than the value at the time SimpleExample is created. Using a lambda to close over a variable makes doing this much easier as well.
public class SimpleExample
{
Func<int> func;
public SimpleExample(Func<int> func)
{
this.func = func;
}
public void DisplayValue()
{
print(func());
}
}
public class RandomClass
{
int myValue = 10;
SimpleExample s;
public RandomClass()
{
s = new SimpleExample(() => myValue);
}
public void WorkWithValue()
{
myValue++;
}
public void Display()
{
print(foo);
print(bar);
s.DisplayValue();
}
}
There is no standard wrapper for the purpose you seek, though a single-element array could be used for that purpose. Alternatively, one could define a simple wrapper type:
public class ExposedValueHolder<T> { public T Value; } // Really simple class, eh?
and then use an ExposedValueHolder<YourStructType> to wrap your object. It's not possible in general to capture something passed as an arbitrary ref parameter, since objects may live indefinitely but byrefs (the things which are actually passed when using ref parameters) may die any time after function they're passed to goes out of scope.

How to use multi properties in class that contain one variable?

I have class named "config" that have private string variable named "param".
I need to get from "config" class "param" variable sometimes as int type sometimes as bool type or string.
As I understand I need create 3 properties in config class,each property have to convert type, as follow:
The first property converts string to int, the second converts string to bool, the third property gets me the string value.
The class should look something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
But I don't know how can those properties be used in accordance to the variable type that I want to get out of class.
This code won't compile - int and such are reserved keywords and cannot be used as identifiers. You can either try naming your properties something like Int32Value, StringValue, etc., or try this:
public static implicit operator bool (Config config)
{
return bool.Parse(config.param);
}
public static implicit operator int (Config config)
{
return int.Parse(config.param);
}
This will allow for much cleaner code:
Config c = GetConfig("foo");
var isFeatureEnabled = false || c;
var spacing = 23 + GetConfig("bar");
You forgot to give your properties names. How would you expect to reference them? Something like this:
class Config
{
private string param;
public int ParamAsInt
{
get
{
return int.Parse(param);
}
}
public bool ParamAsBool
{
get
{
return bool.Parse(param);
}
}
public string ParamAsString
{
get
{
return param;
}
}
}
Note that I also fixed the casing in your calls to .Parse(). C# is case-sensitive. I also replaced the call to bool.TryParse() with bool.Parse(). The former (when used correctly, which this wasn't because it was missing a parameter) will only tell you if it is a bool, it won't tell you what value the bool actually has. (For example, bool.TryParse('false' out someBool) will return true.)
Of course, this code is a bit dangerous. You'll want to start with some more defensive programming to check those values. Basically, look up TryParse() and how to use it correctly. Something like this, for example:
public int ParamAsInt
{
get
{
var tmp = default(int);
if (int.TryParse(param, out tmp))
return tmp;
else
// do something else? throw a specific exception?
}
}
Additionally, what is the purpose of this code? It seems like a very rushed and poor design. For any given value of param (how is that even being set, by the way?) this just sort of randomly tries to expose typed properties for it. If you guess the correct one, you're still left with others that will throw exceptions. Surely there's a much cleaner way to accomplish what you're trying to do. So what are you trying to do?

Pass by reference: Which is more readable/right?

I have the following class:
public class Person
{
public String Name { get; set; }
}
I have a method that takes in Person and a String as parameters:
public void ChangeName(Person p, String name)
{
p.Name = name;
}
Since Person was passed by reference, it should change the Name of the passed instance.
But is this method more readable than the one above?
public Person ChangeName(Person p, String name)
{
p.Name = name;
return p;
}
Is it more readable? No. In fact you may be doing more harm them good.
By having it return a Person object, it might lead you to believe that instead of modifying the Person parameter, it is actually creating a new Person based on p but with a different name and someone could incorrectly assume that p is never changed.
Either way, if you have a method that has no affect on the class it is apart of it should probably be static. That helps you know for sure that it doesn't affect its class. Only have the method return a value if you need it to return a value.
So here is my recommendation for this method:
public static void ChangeName(Person p, String name)
{
p.Name = name;
}
There isn't anything right/wrong with either approach. Depends on what your program needs.
Returning the parameter passed into a method is rarely needed as it is always possible for the user to just use the variable passed as argument instead.
It, however, gives you the flexibility of eventually overriding this implementation, or passing this implementation into another function which accepts delegates with similar signatures. Then you can pass in other implementations that does not return the same Person object.
Do it only if you really need the flexibility.
I would suggest you use one of the following for best readability:
public static void ChangeName(Person p, String name)
{
p.Name = name;
}
public static Person WithName(Person p, String name)
{
return new Person(p) { Name = name };
}
The second one treats the Person object as immutable and does not change the state of the object. The ChangeName function explicitly changes the state of the input object. I think it's important to make a clear distinction between the two types of methods. A good rule of thumb to follow is that a method should not change the state of an object AND return one at the same time.
first of all p is not being passed by reference in the first example. Your second method makes one believe that it is returning a new reference which it is not. So I don't think the second one is any clearer than the first one.
In the case you've described, I would say neither. Its not really clear what you are trying to do with this method. Just use the object and set the property. Inserting a method into the execution path just complicates understanding and creates another dependency on the Person object and its underlying value.
If you are asking a meta question that involves some design over and above the code you have posted, then I am missing it.
The first one is better, because of that the second one might lead you to believe that p is immutable.
But, the whole method is useless since it just calls the setter. Why not just call the setter directly?
I beleve that your 2nd approach is not more readable YAGNI. But if you change it like this
public static class PersonExtensions
{
public static Person ChangeName(this Person p, String name)
{
p.Name = name;
return p;
}
you will have an extensionmethod for a fluent interface a la
new Person().ChangeName("Peter Smith").SendEmail().Subject("Test Mail").Receiver("....)
Here is the definitive reference to understand passing parameters by value/reference.
Looking at the code, why don't you use property?
public string Name
{
set {name = value;}
get { return name; }
}
EDIT: Auto implemented properties
public string Name
{
set;
get;
}

C# Extension methods on "members"

I have some extension methods which could be used like this:
MyType myObject;
string displayName = myObject.GetDisplayName(x => x.Property);
The problem here is that it needs an instance, even if the extension method only needs the type MyType. So if there is no instance, it needs to be called like this:
string displayName = BlahBlahUtility.GetDisplayName((MyTpe x) => x.Property);
Which is not so nice anymore.
Is there a way to write better syntax for such cases?
What I actually want to do is this (pseudo language):
string displayName = MyType.Property.GetDisplayName()
Which of course does not work with C#.
But what about something like this:
string displayName = ((MyType x) => x.Property).GetDisplayName();
This is also not possible (after a lambda, a dot is not accepted).
Any ideas?
Edit:
My "favorite syntax" MyType.Property.GetDisplayName() seems to be misleading. I don't talk about static properties here. I know that this syntax won't be possible. I just tried to show in pseudo language, what information is necessary. This would be ideal, every additional stuff is just syntactical overhead. Any working syntax that is close to this would be great.
I don't want to write a certain extension method. I want an easy, readable and compile time safe syntax, using any language feature.
Have a look at the Express and Reflect classes in the Lokad Shared Libraries. Think they may help out with what you are trying to do. Read more here:
Strongly Typed Reflection in Lokad Shared
How to Find Out Variable or Parameter Name in C#?
From your comment: "I want an easy and compile time safe syntax to get information about members".
This is a very frequently requested feature and has been discussed in the C# team's meetings for about a decade, but has never been prioritised high enough to be included.
This blog post explains why:
http://blogs.msdn.com/ericlippert/archive/2009/05/21/in-foof-we-trust-a-dialogue.aspx
So for now, you're just going to be fighting against a missing feature. Maybe you could post more information about your broader problem and see if people can suggest different approaches.
Update
Without more info about your problem this is just guesswork. But if you have a property that represents a value but also carries additional "meta" information, you could always represent that as a new type and use an "injection" step to set everything up.
Here's a suggested abstract interface to such a "meta property":
public interface IMetaProperty<TValue>
{
TValue Value { get; set; }
string DisplayName { get; }
event Action<TValue, TValue> ValueChanged;
}
The value of the property is just another sub-property, with its type defined by the user.
I've put in the display name, and also as a bonus you've got an event that fires when the value changes (so you get "observability" for free).
To have properties like this in a class, you'd declare it like this:
public class SomeClass
{
public IMetaProperty<string> FirstName { get; private set; }
public IMetaProperty<string> LastName { get; private set; }
public IMetaProperty<int> Age { get; private set; }
public SomeClass() { MetaProperty.Inject(this); }
}
Note how the setters on the properties are private. This stops anyone from accidentally setting the property itself instead of setting the Value sub-property.
So this means the class has to set up those properties so they aren't just null. It does this by calling a magic Inject method, which can work on any class:
public static class MetaProperty
{
// Make it convenient for us to fill in the meta information
private interface IMetaPropertyInit
{
string DisplayName { get; set; }
}
// Implementation of a meta-property
private class MetaPropertyImpl<TValue> : IMetaProperty<TValue>,
IMetaPropertyInit
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
var old = _value;
_value = value;
ValueChanged(old, _value);
}
}
public string DisplayName { get; set; }
public event Action<TValue, TValue> ValueChanged = delegate { };
}
public static void Inject(object target)
{
// for each meta property...
foreach (var property in target.GetType().GetProperties()
.Where(p => p.PropertyType.IsGenericType &&
p.PropertyType.GetGenericTypeDefinition()
== typeof(IMetaProperty<>)))
{
// construct an implementation with the correct type
var impl = (IMetaPropertyInit)
typeof (MetaPropertyImpl<>).MakeGenericType(
property.PropertyType.GetGenericArguments()
).GetConstructor(Type.EmptyTypes).Invoke(null);
// initialize any meta info (could examine attributes...)
impl.DisplayName = property.Name;
// set the value
property.SetValue(target, impl, null);
}
}
}
It just uses reflection to find all the IMetaProperty slots hiding in the object, and fills them in with an implementation.
So now a user of SomeClass could say:
var sc = new SomeClass
{
FirstName = { Value = "Homer" },
LastName = { Value = "Simpson" },
Age = { Value = 38 },
};
Console.WriteLine(sc.FirstName.DisplayName + " = " + sc.FirstName.Value);
sc.Age.ValueChanged += (from, to) =>
Console.WriteLine("Age changed from " + from + " to " + to);
sc.Age.Value = 39;
// sc.Age = null; compiler would stop this
If you're already using an IOC container you may be able to achieve some of this without going directly to reflection.
It looks like you're trying to create a static extension method?
DateTime yesterday = DateTime.Yesterday(); // Static extension.
Instead of
DateTime yesterday = DateTime.Now.Yesterday(); // Extension on DateTime instance.
If this is what you're trying to pull off, I do not believe it is possible in the current version of C#.
It sounds like you are integrating layers a little too tightly. Normally in this type of situation I would let the presentation layer decide the implementation of GetDisplayName() instead of making it an extension of the property itself. You could create an interface called MyTypeDisplayer or whatever you fancy, and let there be multiple implementations of it not limiting you to a single display implementation.
The issue here is that one cannot get a reference to non-static methods via instance MyType.[Member]. These can only be seen through a reference to an instance of the type. You also cannot build an extension method on-top of a type declaration, only on an instance of a type - that is the extension method itself has to be defined using an instance of a type (this T x).
One can however define the expression like this to get a reference to static members:
((MyType x) => MyType.Property)
One could do something similar to string displayName = ((MyType x) => x.Property).GetDisplayName();
The first issue is guaranteeing that the compiler treats your (x=> x.Property) as an Expression rather than an action/func etc...
To do this one might need to do this:
string displayName = ((Expression<Func<PropertyType>>)((MyType x) => x.Property).GetDisplayName();
The extension method would then have to be defined like this:
public static string GetDisplayName<T>(this Expression<Func<T>> expression)
You might also have to define an extension method on top of Expression<Action>> and Expression<Action<T>> if your members are also methods.
You can do a dot after an Expression - this is where the Compile method would reside.
Appended:
I think the static call to the extension method in cases that one doesn't have an instance of the type one needs to do "reflection" on to determine a Members name would be the cleanest syntax still - this way you could still use the extension method when using an instance of a type and fall back to the static call definition => MyExtensionClass.GetDisplayName(TypeOfX x => TypeOfX.StaticMember OR x.Property/Member) when one doesn't have an instance
If you interface your properties, you could make the extension on the interface instead:
namespace Linq1
{
class Program
{
static void Main(string[] args)
{
MyType o = new MyType();
o.Property.GetDisplayName();
}
}
public class MyType
{
public IDisplayableProperty Property { get; set; }
}
public interface IDisplayableProperty
{
string GetText();
}
public class MyProperty1 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public class MyProperty2 : IDisplayableProperty
{
public string GetText() { return "MyProperty2"; }
}
public static class Extensions
{
public static string GetDisplayName(this IDisplayableProperty o)
{
return o.GetText();
}
}
}

Categories