I'm using an MVP pattern to expose field values from my View to my Presenter. I'd like to add an ErrorProvider to my View and add the errors from the Presenter, but that would mean exposing my controls, which I'm not keen on doing. My solution involved creating an ExposableControlValue class that exposes a value generically and has the added function CreateError(string errorMessage).
public interface IExposableControlValue<T>
{
T Value { get; set; }
void CreateError(string errorMessage);
void ClearErrors();
}
My thought was, I'll pass in the Property by reference and now my generic value will essentially point to the Control's backing field. All the ErrorProvider logic could be handled View side and all of the error checking could be handled by the presenter.
Obviously, I'm here because you can't pass the Property by reference, and all of the examples I've seen aren't close enough to my situation that I can decipher them for this example.
I'd also be fine with setting T Get() , Set(T value)methods dynamically if there is a way to do that, but in short, I'd like to mimic having that Property 'live' inside of my class instance.
I'll answer my own question as I finally was able to work this to my desired needs.
Using a factory pattern, I was able to make a new method CreateNew
public IExposableControlValue<T> CreateNew<T>(ErrorProvider errorProvider, Control control, Func<T> get, Action<T> set) {
var param1 = new ConstructorArgument("errorControl", errorProvider);
var param2 = new ConstructorArgument("control", control);
var exposableControlValue = resolutionRoot.Get<IExposableControlValue<T>>(param1, param2);
exposableControlValue.CreateSet(set);
exposableControlValue.CreateGet(get);
return exposableControlValue;
}
I'm using ninject, but the concept is the same. Essentially I'm asking the user for a few dependcies to create a new instance of this class. Then, when I want to actually expose the inner Generic value, I do it like so:
Func<T> get;
Action<T> set;
public ExposableControlValue(ErrorProvider errorControl, Control control) {
...configure my dependcies
}
public T Value { get { return get.Invoke(); } set { set.Invoke(value); } }
Finally, when I actually use the factory CreateNew method, I pass in some arguments depending on the property that I need
_forSomethingBackingField = exposableControlFactory.CreateNew<decimal>(errorProvider, numericUpDownForSomething,
() => { return numericUpDownForSomething.Value; }, (decimal d) => { numericUpDownForSomething.Value = d; });
The decimal is my generic value for the numeric up down. If you wanted to do this with a string, you would simply use string as the generic argument and pass (string s) = > someControlWithTextProperty.Text = s to the anonymous method param. Of course, doing so you would want to make sure that the Property that you are using is actually of the type you pass.
Related
In prior versions of C#, if you wanted to prevent a null reference exception, you needed to build your setters defensively:
public Guid ItemId { get; set; } //foreign key, required
private Item _item;
public virtual Item Item {
get {
return _item;
}
set {
if(value == null) throw new ArgumentNullException(nameof(value));
_item = value;
ItemId = value.ItemId;
}
}
With more modern implementations, this can be condensed a certain amount using the null-coalescing operator and expression bodies:
private Item _item;
public virtual Item Item {
get => _item;
set => _item = value ?? throw new ArgumentNullException(nameof(value));
}
However, I am curious if this could not be condensed entirely down into a variation of the standard reference:
public virtual Item Item { get; set; }
Such that you do not have to define a private item.
Suggestions? Or is the second code block as efficient/simple as I can get?
I am looking for a solution within the current C# framework, not something I have to spend money on. Right now my use case proposition does not support a paid product
Disclaimer: Those are potential 'alternative' ways of filtering out invalid assignments into properties. This might not provide a straight answer to the question, but rather give ideas how to go on about doing it more generically without defining private properties and defining getters and setters explicitly.
Depending on what Item actually is, you could perhaps create a non-nullable type of Item by creating it as a struct.
Non nullable types are called structs. They are nothing new, they are value types which allow to store properties of type int, string, bool etc.
As on MSDN:
A struct type is a value type that is typically used to encapsulate
small groups of related variables, such as the coordinates of a
rectangle or the characteristics of an item in an inventory.
The following example shows a simple struct declaration:
public struct Book
{
public decimal price{ get; set;}
public string title;
public string author;
}
Reference
Edit (Struct should be sufficient if the object is supposed to be non-nullable type, however if we're talking properties of the class then read below.) :
Another way would be using OnPropertyChanged event which is part of the INotifyPropertyChanged interface.
While the event does not explicitly give you the value that has been changed to, you can grab it as it does provide you the property name. So you could run your validation post assignment and throw then, I suppose however it might not be the best option.
void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
var propertyValue = sender.GetType().GetProperty(e.PropertyName).GetValue(sender);
}
Another solution would be using DataAnnotations and add Required attributes on your properties. If I'm not mistaken they will not throw straight away, until you call your own validate function to validate the class, I guess, combined with the above method this would work pretty well and would be pretty generic. Once written you wouldn't have to write your getters and setters explicitly but rather attach just one event to your class and validate it once a property changes.
Here's a small example:
Your Item model for example...
public class Item
{
[Required]
public string Name { get; set; }
}
You would then implement a generic function which would validate all properties.
public bool TryValidate(object #object, out ICollection < ValidationResult > results) {
var context = new ValidationContext(#object, serviceProvider: null, items: null);
results = new List <ValidationResult> ();
return Validator.TryValidateObject(
#object, context, results,
validateAllProperties: true
);
}
Inside that function you would of course throw an exception if validation failed, your results array would contain properties that it failed on an default messages if I'm not mistaken. I believe this is a bit complex, but if you're looking for reducing the number of properties and setter implementations, this could be a step forward. I'm not sure on the overhead etc. Personally, I think on a larger scale, this would be super useful to validate models which are created on the fly from db data or any external source.
Validator Reference | Data Annotations Reference | ValidationResults Reference | PropertyChanged MSDN Sample
I have a large library of code that assumes fields contain a single value of class T. Unfortunately, a new client requires us to have those fields point to List(Of T). I can change the field type, but then all the older code breaks.
In VB I would solve this this way:
Private theList As List(Of T) = new List(Of T)
Public ReadOnly Property Thing() As T
Get
Return theList(0)
End Get
End Property
Public ReadOnly Property Thing(i As Integer) As T
Get
Return theList(i) 'yes, this should throw
End Get
End Property
This relies on VB's ability to have multiple properties with the same name, and the overloading the parenthesis for both parameter passing and indexing. However, C# uses braces for the later, and does not have anything corresponding to a parameterized property. Instead, they have "this[]", and since that name is private you cannot have a "this" with no parameter and another with one (that is true, right?).
But how would I do this in C#? I suspect I can do this with a template, but I'm a bit lost how it would look. I can imagine a List(Of T) subclass with a this[], but then I'm not sure how I would implement the accessors in the other classes so that I still have Thing and Thing[i]. And one caveat, these objects are often used from VBA so it needs to be COM-exportable.
You could add a method to access the property instead if the getter itself.
For example:
class Eg
{
List<T> Test { get; set; }
T GetTest()
{
return Test[0];
}
T GetTest(int index)
{
return Test[index];
}
}
You would then access the property like so (and if wanted you could remove the getter):
Eg eg = new Eg();
T t = eg.GetTest();
or
T t = eg.GetTest(i);
I would Suggest using FirstOrDefault from the Linq library, as List[0] will error on an empty list andd also means that you can't switch to any other datatype that doesn't support index reading
private List<T> items = new List<T>();
public T Item
{
get { return items.FirstOrDefault(); }
}
public List<T> Items
{
get { return items; }
}
however properties don't accept parametrisation except in the form of a this Property
if you used a method for this then that will work eg
public T GetData()
{
get { return items.FirstOrDrfault(); }
}
public T GetData(int index)
{
get { return items[index]; }
}
If you need to make your class provide functionality to a new client, you might need to change your design to have them depend on an Interface, rather than the specific implementation of the class.
That said, if sounds like your new client needs a different class, which might contain a collection of your old class, rather than changing your class to fit the new client.
I am working on an application where a form will be created at runtime based on data from a database. It currently uses reflection to create the control and add it to the form.
With this I can easily dynamic create a form at runtime, but next I ran into the issue of how to access the currently selected, eg: TextBox.Text versus DropDownList.SelectedValue. To "fix" this, I created an interface with the method of GetValue. With this, I create a new class and inherit from the respective control and implement the interface.
Now I can easily iterate over the form controls to see if they implement the interface and then get the value of the control.
The question to all of this is: Is this the best way to accomplish this?
To note: I fully expect the controls available to build these forms to get to 15+.
Example of class:
public interface IFormField
{
string GetId();
object GetValue();
}
public TextBox : System.Web.UI.WebControls.TextBox, IFormField
{
public string GetId()
{
return ID;
}
public object GetValue()
{
return Text;
}
}
While I like interfaces, as noted with the "create a new class and inherit from the respective control" .. using new interfaces require that the underlying types are modified. This is not always practical for this case. So, while I won't claim that interfaces aren't appropriate here, I will provide alternative ideas.
This first approach uses a companion object which knows about the control, and how to get the value from the control. This class could use an interface but it is not required here. It allows delaying of the fetcher (in a well-typed manner) but also requires that it's explicit set per companion instance.
interface IWithValue {
string Value { get; }
}
class ControlCompanion<T>: IWithValue where T: Control {
IFunc<Control, string> readValue;
public T Control { get; private set; }
public string Value { get { return readValue(Control); } }
public ControlCompanion (T control, IFunc<T, string> readValue) {
Control = control;
this.readValue = readValue;
}
}
// this is typed narrowly here, but it could be typed wider to
// the actual ControlCompanion if needing additional information
// or actions wrt. the particular control
var valueAccessors = new List<IWithValue>();
var textBox = new TextBox();
valueAccessors.Add(new ControlCompanion(textBox, (c) => c.Text));
var comboBox = new ComboBox();
valueAccessors.Add(new ControlCompanion(comboBox, (c) => c.SelectedValue));
var allValues = valueAccessors.Select(v => v.Value);
Another alternative is to create a function that knows how to extract the values. Because these controls are "created dynamically" (e.g. of type Control) we can't use method overloading directly and must therefore accept the more general type and use some form of reflection or type refinement.
string GetValue(Control c) {
// using this form will allow invalid path detection
TextBox tb;
ComboBox cb;
if ((tb = c as TextBox) != null) {
return tb.Text;
} else if ((cb = c as ComboBox) != null) {
return GetValue(cb);
} else {
throw new Exception("Unsupported control");
}
}
// but we could use overloading once refined ..
string GetValue(ComboBox cb) {
return cb.SelectedValue;
}
Of course, the above two approaches could be combined1 - e.g. a GetValue function that use a per-type extractor (similar to ControlCompanion but independent of a control instance) looked up by a map/dictionary based on the actual type of the control object. If one didn't even want to maintain the map/dictionary manually, assembly reflection could load these per-type extractors automatically - oh, the possibilities and possible complexity!
Along the same lines but more general than the above suggestion is to use Type Converters which is quite a complete (if not complex) setup to handle converting types - even when those types cannot be modified or extended.
There are several different possibilities, and while extending controls and adding interfaces does usually work (it requires the controls can be registered as safe and created by the particular refined implementation), it is limited to cases in which said types can accommodate such changes.
1Okay, here is a rough idea for a general "switchless" GetValue. Note that it separates the control instance from the "fetcher". In fact, such an inversion could even be used to "get companions" to avoid explicit wrapping as in the first example.
interface IFetchValue {
string FetchValue(Control c);
}
abstract class Fetcher<T>: IFetchValue where T : Control {
abstract protected FetchControlValue(T c);
public string FetchValue (Control c) {
return FetchControlValue((T)c);
}
}
class TextBoxFetcher: Fetcher<TextBox> {
protected string FetchControlValue (TextBox tb) {
return tb.Value;
}
}
class ComboBoxFetcher: Fetcher<ComboBox> {
protected string FetchControlValue (ComboBox cb) {
return cb.SelectedValue;
}
}
// This could be initialized via reflection of all
// Fetcher<T>/IFetchValue types with a bit more work.
IDictionary<Type, IFetchValue> map = new Dictionary<Type, IFetchValue> {
{ typeof(TextBox), new TextBoxFetcher() },
{ typeof(ComboBox), new ComboBoxFetcher() },
};
string GetValue(Control c) {
IFetchValue fetcher;
// This should be smarter to also try parent types or
// check general assignability.
if (c != null && map.TryGetValue(c.GetType(), out fetcher)) {
return fetcher(c);
} else {
throw new Exception("Whoops!");
}
}
In addition, your favorite DI/IoC framework might support similar resolve capabilities which would then just push this maintenance into the configuration. Again - many ways, and many ways to make it complicated.
Pretty much. This is one of the main reasons why inheritance/polymorphism are useful. It allows calling code to deal with a generic collection which could actually have many deriving types and deal with them all as if they were the same thing.
If you only have a two or three types it might be simpler to skip this, but as the set of types you can operate on grows this rapidly becomes the best option. Also, I'd like to point out that I don't deal with WinForm types very much, there may already be some support for this type of behavior (which you'd be duplicating) that I don't know about.
You can do it this way (just to state the obvious...), but personally I wouldn't have. Extending a number of controls when all you are doing is adding a single method as part of an interface implementation is a reasonably long winded way to do it.
I would have used a helper method which takes a Control as its input, and checks the type of the control (via casting in lieu of a more language specific option) and then returns the control's value as an object.
The purpose of an interface is to establish a contract irrespective of the actual implementation, so you haven't used it incorrectly, you've just done more work than you really needed to.
Your approach is good and correct if it fullfils your needs and simplifies life.
I want to show an alternative way of control's value retrieval, the way of how it is accomplished in ASP.NET Web Forms itself. This approach could be useful if you don't want to bother with inheritance and if you are using standard input controls or all your controls are decorated with ValidationPropertyAttribute (which is mandatory if you want to use standard validation controls with your custom ones).
To retrieve value of any standard input control we need to use BaseValidator.GetValidationProperty method. This method returns PropertyDescriptor instance for validation property which holds control's value (except ListItem, but this case is covered in code snippet).
So the complete code for value retrieval would be:
public static string GetControlValue(Control c)
{
// This code is copied as-is from BaseValidator.GetControlValidationValue method
PropertyDescriptor prop = BaseValidator.GetValidationProperty(c);
if (prop == null) {
return null;
}
object value = prop.GetValue(c);
if (value is ListItem) {
return((ListItem) value).Value;
}
else if (value != null) {
return value.ToString();
}
else {
return string.Empty;
}
}
Rephrased the question. Scroll down for the original
Ok, maybe I should have given you the whole picture. I have many classes which look like this:
public class Movement : Component
{
private Vector3 linearVelocity;
public Vector3 LinearVelocity
{
get
{
return linearVelocity;
}
set
{
if (value != linearVelocity)
{
linearVelocity = value;
ComponentChangedEvent<Movement>.Invoke(this, "LinearVelocity");
}
}
}
// other properties (e.g. AngularVelocity), which are declared exactly
// the same way as above
}
There are also classes called Transform, Mesh, Collider, Appearance, etc. all derived from Component and all have nothing but properties which are declared as described above. What is important here is to invoke the ComponentChangedEvent. Everything works perfectly, but I was looking for a way where I don't have to rewrite the same logic for each property again and again.
I had a look here and liked the idea of using generic properties. What I came up with looks like this:
public class ComponentProperty<TValue, TOwner>
{
private TValue _value;
public TValue Value
{
get
{
return _value;
}
set
{
if (!EqualityComparer<TValue>.Default.Equals(_value, value))
{
_value = value;
ComponentChangedEvent<TOwner>.Invoke(
/*get instance of the class which declares value (e.g. Movement instance)*/,
/*get name of property where value comes from (e.g. "LinearVelocity") */);
}
}
}
public static implicit operator TValue(ComponentProperty<TValue, TOwner> value)
{
return value.Value;
}
public static implicit operator ComponentProperty<TValue, TOwner>(TValue value)
{
return new ComponentProperty<TValue, TOwner> { Value = value };
}
}
Then I would use it like this:
public class Movement : Component
{
public ComponentProperty<Vector3, Movement> LinearVelocity { get; set; }
public ComponentProperty<Vector3, Movement> AngularVelocity { get; set; }
}
But I am not able to get the instance where LinearVelocity comes from nor it's name as string. So my question was, if all of this is possible...
But it seems that I have no option other than keep doing it the way I was, writing this logic for each property manually.
Original Question:
Get instance of declaring class from property
I have a class with a property:
public class Foo
{
public int Bar { get; set; }
}
In another context I have something like this:
Foo fooInstance = new Foo();
DoSomething(fooInstance.Bar);
Then, in DoSomething I need to get fooInstance from having nothing but parameter. From the context, it is save to assume that not any integers are passed into DoSomething, but only public properties of ints.
public void DoSomething(int parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Is that possible at all? Using reflection, or maybe a custom attribute on the property Bar?
Why do you want to send just a property to DoSomething, send it the whole object :), so it would become,
DoSomething(fooInstance);
Your function will then accept object instead of parameter. You can use an overload of this function to make sure that old code doesn't break.
There are several ways to deal with implementing INotifyPropertyChanged. You're doing almost the same thing, except you don't implement the interface and raise the event in a different way. But all of the solutions apply for you too.
Like you do, call a method with a string parameter: OnPropertyChanged("Property").
Call a method with a lambda that uses the property: OnPropertyChanged(() => Property). The advantage of this is that it's compile-time checked for typos and refactoring-friendly.
Use caller information to inject the name of the property: OnPropertyChanged(). This will work in C# 5.
Use something like Castle DynamicProxy to create a derived class at runtime that will call the method for you. This means you need to make your properties virtual and that you need to create instances of the class only through Castle.
Use an AOP framework to modify the code of your properties after compilation to call the method.
there's no way to get fooInstance from parameter. parameter is passed by value, and is only a copy of the value of fooInstance.Bar, it no longer has anything to do with fooInstance
That being said, the obvious solution is to write DoSomething like this
public void DoSomething(Foo parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Property is just a field, which returns reference to some object on heap (i.e. its address). If property is not of reference type, it returns value of object.
So, when you do something like
DoSomething(fooInstance.Bar);
You just passing address of object Bar to method.
If Bar is reference type (i.e. class). Imagine that Mr.Foo has an address of Mr.Bar (462 for Marion County, Indiana). Mrs.CLR asks Mr.Foo for address of Mr.Bar. And then tells this address to somebody who needs address of Mr.Bar. How somebody will know, that CLR asked Foo about address of Bar? He received only an address 462 for Marion County, Indiana.
In case of value objects (int, double, structs etc), Mr.Foo has a cool mp3 track named Bar. Mrs. CLR creates a copy of that mp3 track and sends it to somebody. How somebody will know, that his mp3 track Bar is a copy of Mr.Foo's track?
So, if you want somebody to know about Mr.Foo, you need to pass an address of Mr.Foo to him:
DoSomething(fooInstance);
With this address somebody can visit Mr.Foo and ask him about address of Mr.Bar, or create a copy of his mp3 track :)
I am working on an ASP.Net MVC website and I am stuck on a getting my C# code using generics to play nice with my views.
I have a Controller that passes a Model to a View (so far so good). The Model is of type IDescribedEnumerable<T> with some constraints on T, among those is the constraint that T inherits from an interface (IDescribedModel).
I can easily write a View that accepts an IDescribedEnumerable<Country> and that will work as long as T is in fact the type Country.
However, I'd also like to write a default view that accepts an IDescribedEnumerable of <<whatever>> and that will render it. This should be entirely possible. I don't always need to know the specific type of the Model. Often just knowing that it's an IDescribedModel is enough.
As long as I stay in C# there is no problem. When I don't care about the specific type I just declare methods and objects as accepting a <T>. When I do care I declare them as accepting Country.
But:
(1) If I want to render a View I have to pick an type. I can't just say Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>" I have to specify an existing type between the <>. (even if I were to inherit from ViewUserControl I'd have to cast it to an IDescribedEnumerable<<something>>.
(2) Ideally I'd say that Model is IDescribedEnumerable<IDescribedModel> in the default View and IDescribedEnumerable<Country> in the specific implementation. However, then my Controller needs to know whether he's going to render to the default View or the specific view. It is not possible to simply cast an object that is IDescribedEnumerable<Country> to IDescribedEnumerable<IDescribedModel>. (IIRC it is possible in C# 4, but I'm using 3.5)
So what should I do? All options I can think of are very sub-optimal (I'm not looking forward to removing the generics and just casting objects around, nor to copy pasting the default view 65 times and keeping the copies synchoronized, nor going reflection gallore and creating an object based on a known Type object)
while awaiting some C# genius to come along with the answer to all my problems I have implemented the trick that IEnumerable also uses:
I added a method public IDescribedEnumerable<IDescribedModel> AsIDescribedModels() to the IDescribedEnumerable interface and created a new class GenericDescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel>. In my DescribedEnumerable<T> class I create a GenericDescribedEnumerable and return that. In the GenericDescribedEnumerable I return this
in full code:
public interface IDescribedModel<T> : IDescribedModel{
T original {
get;
}
}
public interface IDescribedEnumerable {
IDescribedEnumerable<IViewModel> AsIViewModels();
}
public interface IDescribedEnumerable<T> : IDescribedEnumerable
where T : IDescribedModel{
IEnumerable<T> GetViewModels();
}
public class DescribedEnumerable<T> : IDescribedEnumerable<IDescribedModel<T>>{
public DescribedEnumerable(IEnumerable<T> enumerable) {}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return new GenericDescribedEnumerable<T>(/*allProperties*/);
}
public IEnumerable<T> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new DescribedModel<T>( obj);
yield return vm;
}
}
}
public class GenericDescribedEnumerable<T> : IDescribedEnumerable<IViewModel>{
//pass in the constructor everything you need, or create in the
//constructor of DescribedEnumerable<T>
public GenericDescribedEnumerable(/*allProperties*/) {
}
public IEnumerable<IViewModel> GetViewModels() {
foreach ( T obj in _enumerable ) {
var vm = new PlatoViewModel<T>( obj );
yield return vm;
}
}
public IDescribedEnumerable<IViewModel> AsIViewModels() {
return this;
}
}
Yeah, that will work or use the model as object, and cast it appropriately. That's the approach the ViewPage class uses, with ViewPage and ViewPage : ViewPage.
Inherits="System.Web.Mvc.ViewUserControl<IDescribedEnumerable<T>>"
...
Model.Cast<IModel>()