Generic type list issue - c#

I have following structure:
public class Base : BaseViewModel
{
public string Name{ get; set; }
}
public class SubBase<T> : Base
{
public virtual IEnumerable<T> Values{ get; set; }
private T selectedValue;
public T SelectedValue
{
get { return selectedValue; }
set
{
selectedValue= value;
OnPropertyChanged();
}
}
}
The problem is that I create lists of BaseFiltr as follows
ObservableCollection<BaseFiltr>
and then I have one of elements from list which is of type BaseFiltr and I want to get its SelectedValue property but unfortunately it is not possible since it is placed in derived class. I cannot place this property in BaseFiltr since I would have to mark it as generic. BaseFiltr is created only for list's purpose to avoid setting as follows:
ObservableCollection<BaseFiltr<some type>>
Any suggestions what might be done? Thank you in advance.

I have one of elements from list which is of type BaseFiltr and I want to get its WybranaWartosc property
You have a fundamental problem - BaseFiltr does not have a WybranaWartosc property - only SubBaseFiltr<T> does. You could check each item to see if it's a SubBaseFiltr<T> and then cast and probe it's WybranaWartosc property.
BaseFiltr is created only for list's purpose to avoid setting as follows: ObservableCollection<BaseFiltr<some type>>
It appears you're sacrificing proper typing for a slight decrease in complexity. If your collection is really a collection of SubBaseFiltr<T> objects, then use that type.

Related

Can you use a property without a field in C#?

In C#, can you use a property without a field?
Edit for clarification:
private string _name;
public string Name
{
get { return _name; }
set { _name value; }
}
It seem's like they are always paired, is there a circumstance where we don't use the field at all?
All properties must have a field, assuming they are simple properties to store a value (*). However, the language (as of version 3.0) offers a way to declare the field implicitly. For example:
public int Value { get; set; }
That would declare a property named Value with an implicit field backing it and the getter and setter both public. You can include an accessibility keyword on either the getter or setter to restrict access to the property. For example:
public int Value { get; private set; }
In this case, only the owning type may call the setter, but any class can call the getter.
The next version of C# will have additional features for dealing with these "automatic properties", allowing you to provide a concise initialization syntax for them. For now, you have to initialize them in a constructor.
EDIT: based on your edited question, it seems worthwhile to address this specific question: "is there a circumstance where we don't use the field at all?"
The answer to that is, it's not common for no field to be involved at all. But it is possible, and it's not uncommon for a property to not use a field as storage for the property. For example, imagine a Rectangle object with an Area property:
class Rectangle
{
public double Width { get; private set; }
public double Height { get; private set; }
public double Area { get { return Width * Height; } }
}
Obviously there are fields involved (two of them), but there is not a field specifically dedicated to the Area property.
Another example would be where the property delegates. For example, in a WinForms Form subclass, it's common to expose specific control values via a property:
class MyForm : Form
{
public string EditText
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
}
Again, the textBox1 field is being used here. But it actually represents something other than the property itself. The property is using a member of the object that field references.
I hope that clarifies the relationship between fields and properties adequately for you. Please feel free to ask for further clarifications if needed.
(*) Note that the only real rule for properties is that they have at least one of the getter or setter, and those methods can do whatever you want. I assume we are talking about simple value-based properties here.
A property is not required to have a field
public string Version
{
get
{
return "1.3.Awesome";
}
}
If you're asking what I think you are, the answer is yes, you just put get; set; inside the property declaration. C# encapsulates a variable for you.
EDIT: example
//no need for field declaration
public string Name
{
get;
set;
}

Get the DisplayMember value of any object in ListBox in WPF

I have a ListBox, and it's items consist of custom class objects (can be any class).
Then I set the DisplayMemberPath so the ListBox shows the right property of that custom class fine.
Now I need to enumerate the Items list of ListBox, and get the DisplayMember value of each item in the list, without knowing the type of the class in the list. Is there any way to get this DisplayMember value without Reflection?
In WPF, you don't need to implement an interface, or a base class for a container control to read the value of a property. In an ideal world, it would make sense to declare a base class or interface and have all of your custom classes extend, or implement these, but the benefit of that is really to keep your data type safe.
For example, in WPF, this is perfectly legal and will work just the same:
public class RadioButtonData
{
public string Label { get; set; }
public bool IsSelected { get; set; }
}
public class CustomData
{
public string Label { get; set; }
public string Value { get; set; }
}
...
private ObservableCollection<object> objects = new ObservableCollection<object>();
public ObservableCollection<object> Objects
{
get { return objects; }
set { objects = value; NotifyPropertyChanged("Objects"); }
}
...
Objects.Add(new RadioButtonData() { Label = "Some Value" });
Objects.Add(new CustomData() { Label = "Another Value" });
...
<ListBox ItemsSource="{Binding Objects}" DisplayMemberPath="Label" />
So as long as your various classes have the same name of property, then they will all be displayed in the same way, like above. They don't even have to be of the same type... just as long as the name matches that used in the ListBox.DisplayMemberPath property.
UPDATE >>>
Ah sorry, I misunderstood your question. In the case that you want to access these property values in code, then you have four basic options:
Define an Interface with a particular property and make your custom classes implement it.
Declare a base class with a particular property and make your custom classes extend it.
Create a (potentially long) section of if else statements that checks the type of each object and then accesses the relevant property.
Use reflection.
In my personal opinion, I would recommend options 1 or 2 first, then 4 and lastly 3. I'm really not sure what you have against reflection, but it's really not that bad, or slow... I'd certainly prefer to use it rather than having an else if statement for every possible type used.

What is it called when a class property is an instance of another class?

Very basic question here, look at my property Order in my customer class. Wondering what is the formal name of a property type like this is (yes, this could also be a list).
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public Order Orders { get; set; } // what am i called?
}
public class Order
{
public int ID { get; set; }
public string SomeProperty { get; set; }
}
Its the same thing. Its called a "Property". There is no different name for it. Consider your SomeProperty which is of type string. string is also a class and SomeProperty is its object. Same convention with your class would follow as well.
From C# Language Specification.
1.6.7.2 Properties
A property is declared like a field, except that the declaration ends
with a get accessor and/or a set accessor written between the
delimiters { and } instead of ending in a semicolon.
So the term "property" in C# is associated with the accessors (get/set)
from ECMA-334 8.7.4:
A property is a member that provides access to a characteristic of an object or a class.
It doesn't matter what type the property accesses. The property itself is just to provide access to it.
So, bottom line, a property is a property no matter what type it accesses.
It's just a property - there's not a formal name for it.
The concept itself is called Composition. Basically, you want to be able to use a Customer object to get information about an Order, but you don't want the logic that gets that information to live in Customer. So, you have a member who is an Order and Order encapsulates the Order behavior.
You could say that a Customer is composed of Order along with other values.
Have a link: http://www.javaworld.com/jw-11-1998/jw-11-techniques.html
Not that you asked this, but you probably will want an actual collection of Orders. You could start with
public List<Order> Orders;
It's still a property. It just gets/sets an object, which is an instance of a class.

properties in C#

Why are we able to write
public int RetInt
{
get;set;
}
instead of
public int RetInt
{
get{return someInt;}set{someInt=value;}
}
What is the difference between the two?
This feature is called Auto implemented properties and introduced with C# 3.0
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.
class Customer
{
// Auto-Impl Properties for trivial get and set
public double TotalPurchases { get; set; }
public string Name { get; set; }
public int CustomerID { get; set; }
For your question
What is the difference between the two?
In your case, none. Since you are not doing anything while setting or retrieving the value, but suppose you have want to do some validation or want to perform other types of check then :
private int someInt;
public int RetInt
{
get
{
if (someInt > 0)
return someInt;
else
return -1;
}
set { someInt = value; } // same kind of check /validation can be done here
}
The above can't be done with Auto implemented properties.
One other thing where you can see the difference is when initializing a custom class type property.
If you have list of MyClass
Then in case of Normal property, its backing field can be initialized/instantiated other than the constructor.
private List<MyClass> list = new List<MyClass>();
public List<MyClass> List
{
get { return list; }
set { list = value; }
}
In case of Auto implemented property,
public List<MyClass> SomeOtherList { get; set; }
You can only initialize SomeOtherList in constructor, you can't do that at Field level.
How are these two different ?
There are different at least by 2 points:
In normal property you have to define a field before (someInt in your case)
In normal property you can set a breakpoint into the set/get modifiers, instead in auto property can not do that.
In other words: if you need "just property", use auto-properties, if you need more control over workflow (raise an event on set, debug, run other stuff inside), use "normal" properties.
These are auto implemented properties. Please see http://msdn.microsoft.com/en-us/library/bb384054.aspx for more info.
Basic reason why these were introduced was to reduce the overhead of programmer of creating a private variable like someInt which had little use than being used in a property.
Actually these aren't really different, in both cases you have a private field that corresponds to your property, but in the first case it is generated by the compiler and hidden.
If you need to use the variable behind the property quite often in your class, I think it's better to declare your property the old way (2nd one), because each time you will access it this will call the getter if you do it the "new" way.
If you only need it to be used from outside your class (or in most of cases), then you can go with the "new" way (1st one)

Binding Custom List Property To DatagridView

I have a problem that is difficult to explain. Essentially I have a list of a certain class we can call MyObj. One of the properties of this object is a custom list itself. I would like to bind this List to a dataGridView and have this particular property that is also a list show up. Any ideas? Am I being clear enough? :-P..
Here is the idea. I have my own custom list object overriding the ToString() method:
public class CategoriesList : List<Category>
{
public override string ToString()
{...}
}
This is used as a property in an object such as:
public MyObj
{
public string Property1 {get; set; }
public string Property2 {get; set; }
public CategoriesList Categories {get; set; }
}
In turn, I have a list of these objects such as:
List<MyObj> myDataSouce = SomeRepository.GetMyObjList();
Where I bind this to a datagrid view:
MyDataGridView.DataSource = myDataSource;
Property1 and Property2 are automatically generated. Is there any way to have the CategoriesList property be added as well? I previously thought Overriding the ToString() method on a class would be enough..
I am really lost on this one as I have no idea how to even google for it :-P
Assuming that you'd like to display a specific value in place of the list in the datagridview, you'll want to use a custom TypeConverter. Otherwise you'll need to place a control in the datagridview column that supports lists, like a drop down list and bind to that.
For the former:
Basically decorate your categories property with a custom typeconverter:
[TypeConverter(typeof(MyConverter))]
public CategoriesList Categories { get; set; }
Then use a custom type converter that basically tells the datagrid that when it encounters the categories property what do display:
public class MyConverter : TypeConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is CategoriesList) {
return value.ToString();
}
return base.ConvertFrom(context, culture, value);
}
}
You'll need to add your column to be databound manually by adding an unbound column and specify the DataPropertyName for the property to be mapped to that column, in this case "Categories"
If you're looking to display second level properties as well then this may help:
http://blogs.msdn.com/b/msdnts/archive/2007/01/19/how-to-bind-a-datagridview-column-to-a-second-level-property-of-a-data-source.aspx
This might help... look at my answer there, I haven't tried it with a property that is also a type of list but I think the idea is the same.
Or this one as well, I also have an answer there with a sample code too...

Categories