Bidirectional Binding of two Non-String Properties (JavaFX) - javafx

I'd like to bind two properties of different types to each other bidirectionally.
I have an interface:
interface Gateway<F, T> {
T to(F item);
F from(T item);
}
which allows me to convert an object of one type, to an object of another type.
Optimally, I'd have a function:
void bindBidirectional(Property<F> first, Gateway<F, T> converter, Property<T> second) {
...
}
which would allow me to easily bidirectionally bind two properties, so long as I have an object that can map values of one type to values of another, and back.
How would I implement binding like this?
Note: There are already convenience methods for this kind of binding as long as one of the Property's types is a String. I'd like a more generic method, similar to this, that will allow me to convert between any two types.

Related

Class inheritance in DocumentDb

I am trying to figure out best way to model class inheritance in DocumentDb.
Say my classes are structured as
class A
property X
property Y
property Z
class B inherits from A
property W
Is there a built in support to handle this? If I use Lambda expressions in my client code, will they be able to distinguish between the types automatically?
Will the following query only return objects of type B back? Or will it also consider instances of base class A?
var bCollection = from o in client.CreateDocumentQuery<B>(collectionLink)
where X > 2
select o;
Is there a built in support to hand this? If I use Lambda expressions in my client code, will it be able to distinguish b/w the types automatically?
Yes, you can use lambda syntax in client side, as long as you specify the specific type in the generic method, as client.CreateDocumentQuery<YourType>(collectionLink).
Will following query only bring objects of type B back? Or will it also consider instances of base class A?
DocumentDB is a schemaless store and does not store type information. The overloaded generic methods provided in the client are syntactic sugar, to let you easily create queries.
All queries are evaluated against json documents, which do not have type information.
Inheritance scenario
So, if you fire a query for a property which is present only in your derived class, you will get values corresponding only to your derived class. But, if the property you are querying on is in both base class and derived class, you'll get back both results. For example, in your case filtering on W would give you results of only class B, but filtering on X, Y or Z would give you values for both classes A and B.
Classes with shared schema in same collection
Note that this does not just happen in the base-derived class scenario. Same behavior would happen if you have 2 separate classes, which do not inherit each other, but have a property with the same name. Querying on that property will return results of both classes.
For example, if you have 2 classes which are stored in the same collection:
class A1 { int x; }
class A2 { int x; }
Even if you form your query using the client.CreateDocumentQuery<A1>(collectionLink), results of both class A & B will be returned. As I mentioned earlier, the type specification in the client is just to make your life easier while forming the query.
I you want to be able to query different types of data, having shared schema elements, stored in the same collection - I would recommend having a separate property to store the type information manually and filtering on that property.
class DocumentDbData
{
string DataType;
DocumentDbData(string type) { DataType = type;}
}
class A1 : DocumentDbData
{
string x;
A1() : base("A1")
}
class A2 : DocumentDbData
{
string x;
A2() : base("A2")
}
The query, client.CreateDocumentQuery<A1>(collectionLink).Where(d => d.DataType == "A1" && d.x == "xvaluefilter") will now return only data for class A1.
I use node.js not .NET, so I don't recognize the CreateDocumentQuery<B> syntax. Is there a way to inspect the actual query that is sent by the .NET SDK to see if there is something added to the WHERE clause to restrict the results to type B? Alternatively, is there some field like _Type added to your documents without your intervention? I highly doubt the query clause you provided is so modified. I'm less sure that an _Type field isn't added, but I consider it less than 50% likely. My instinct is just that the <B> specification on the CreateDocumentQuery simply casts the returned objects to type B for you. I have no idea if that will cause an error if your result set included class A objects or if it will use null or some other default for missing fields.
Assuming all of the above, you'll probably have to model class hierarchy yourself. I have modeled this in two different ways:
Use a materialized array to indicate the entire class hierarchy for each document. So, ["Animal", "Mammal", "Cat"]. Then when you want all Mammals, you can query with WHERE "Mammal" IN c.class.
More recently, I've switched to having a separate field for each type that something is. So, isAnimal = true, isMammal = true, and isCat = true. This is more of a mixin approach, but you can still model class hierarchies this way.

Qt Proxy with type of source object

I have class, say MyClass, inherited from QSqlRelationalTableModel and I need to transpose it (change rows with columns).
This solution was found.
Is it possible to get transposed object of type MyClass after using the proxy? If not, are there any other ways to do it?
Thank you!
EDIT
I wanna use is like this:
MyClass* myObject = new MyClass(this, db);
TransposeProxyModel* trans = new TransposeProxyModel(this);
trans->setSourceModel(myObject);
ui->tableViewDb->setModel(trans);
ui->tableViewDb->setItemDelegate(new QSqlRelationalDelegate(ui->tableViewDb));
It is necessary to paste object of MyClass (or QSqlRelationalTableModel) into QSqlRelationalDelegate.
(edited as per question clarification)
Why do you need to pass the source model into the QSqlRelationalDelegate? If you use the stock delegate then the delegate needs to operate on top of data that it visualizes (data from TransposeProxyModel).
If you have a custom subclass of QSqlRelationalDelegate and you want to access the source data from there for any reason, then you can pass myObject as a second argument to delegate constructor, or you can access it through QModelIndex::model() methods of the index passed to delegate's methods.

Dynamically chose type depending on JSON content

In an ASP.NET MVC 4 application I get a JSON response from an external server that contains an array of "fields". Each field is of an individual type and contains an array of values of that type.
I'd like to deserialize that JSON either into a DynamicObject so that I can access the indivudual value propreties or I need some kind of a child class chooser which decides which class, derived from a "ValueBase" class, is needed to access the different properties of the individual value object.
I hope you know what I mean... it's a little bit complicating.
I've already tried to deserialize it into a DynamicObject (a class that derives from DynamicObject that is). But I get error messages when accessing that object's dynamic properties in the View that the properties I'd like to display don't exist.
So how does a class that derives from DynamicObject have to look like to accept and grant access to the individual differen "value"-properties provided by the JSON code?
And if that wasn't possible or the wrong way to go, how would I have to implement a suitable type chooser class?
Thanks a lot!
I've kinda solved it myself.
Instead of directly converting the returned JSON object (a JSON array to be more precise) into a specific class I fetch it as a dynamic and give it into the constructor of a class that contains a collection of instances of another class the object actually ought to be of (I get a JSON array returned from the webservice anyway). In the constructor of the collection class I decide depending on a value of the JSON object of which inherited class the new object is gonna be and put that into the collection. Yeah, I walked that way afoot somehow but it works.
Looks like this:
public CollectionClass(dynamic dyn)
{
foreach(var item in dyn.items) {
switch((string)item.external_id) { // might have used a Dictionary instead but...
case "member":
this._collection.Add(new Member(item));
break;
case "date":
this._collection.Add(new Date(item));
break;
default: break;
}
}
}
The Member-class itself contains a similar constructor which also requires a dynamic parameter. And it also "builds itself up" depending on values inside the item.
If there's any easier way or a "royal road" of achieving this I'd be grateful for any further advice.

Casting a C# List<>

I have what seems to be a simple problem but one that I can't seem to find answers to. I have a class with properties. One of those properties returns a List. I have a method that cycles through all properties of any kind of class and produces a TreeNode for that class (a communication log application). When I come across the property identified as a List, I don't know how to cast the property.GetValue properly. the property.PropertyType is known but what ever I try, I get a compilation error or a runtime error.
Here is what I'm trying to do...
foreach (PropertyInfo prop in props)
{
if(prop.PropertyType.Namespace == "System.Collections.Generic")
{
List<object> oList = prop.GetValue(data, null);
MessageBox.Show(oList.Count.ToString())
}
}
If I put a breakpoint on the GetValue line, the prop parameter knows that it's a list of "myclass" items with three elements. I just can't cast it to either a list of objects (which would be fine) or cast it to a list of actual "myclass" elements which would be even better. How do I cast the return value of PropertyInfo.GetValue (an object) to its List?
First of all, it's not enough (or needed in this case at all) to check the namespace. You can check if prop.PropertyType is an instance of ICollection (you can use IsAssignableFrom). I'm suggesting ICollection because you only seem to care about the Count.
You can then cast it to an ICollection (non-generic) and run Enumerable.Cast, like:
IEnumerable<MyClass> res = ((ICollection)prop.GetValue(data,null)).Cast<MyClass>();
MessageBox.Show(res.Count().ToString());
The advantage over converting directly to List is that this will work with any collection. But if you don't need that, you can try what the other answer suggests.
did you try
prop.GetValue(data, null) as List<YourClass>;
I guess you want contravariance.
Are you trying to do so?
List<object> list = (List<Product>)object;
List<object> and List<Product> wouldn't be treated as the same type.
C# 4.0 introduced covariance and contravariance for interface and delegate generic parameters, but anyway, IList<T> doesn't have contravariance.
In my humild opinion, I believe you'll need to reconsider your object graph!
PD: Just comment out if you want guidance for that!

What's behind the FXCop rule CA1061 "Do not hide base class methods"?

Why is the FxCop rule CA1061 a bad idea?
The docs state that this rule should not be suppressed. If I have class like so:
public class Set<T>
{ List<T> m_backingList;
public bool Contains(T value)
{
return m_backingList.Contains(value);
}
}
then I add a specific implementation like this:
public class CaseInsensitiveSet : Set<String>
{
public bool Contains(object value)
{
string stringValue = value as string;
if (stringValue == null)
return false;
return base.Contains(stringValue);
}
}
the FxCop complains, but I'm not certain why this is such a bad idea. Is there some problem I don't see with this implementation?
The rule states why you're getting the message:
A method in a base type is hidden by
an identically named method in a
derived type when the parameter
signature of the derived method
differs only by types that are more
weakly derived than the corresponding
types in the parameter signature of
the base method.
In your child class, the Contains method takes an object which is more weakly typed than string and therefore hides the parent.
The reason you're getting the warning from FxCop is that this might not be an intentional design choice (since you're not overriding anything or using the new keyword).
Even if it is an intentional design choice, I would argue that it's not necessarily a good one. If you already know that the collection is going to contain strings and nothing else, why would you provide a Contains method that takes anything other than a string? It may appear that you're adding flexibility into the design but, in the end, you're really only going to confuse other developers.
There are also other naming options instead of calling the method Contains which wouldn't hide (intentionally or not) the base Contains method.
Ask yourself: do I want the users to be able to call the base class method on an instance of the derived class.
If the answer is yes: don't hide the base method, as this will make it more cumbersome to use it.
If the answer is no: don't derive from this class, or else they can still access the base method by casting the object to the base class.
http://msdn.microsoft.com/en-us/library/ms182143(VS.80).aspx
A method in a base type is hidden by
an identically named method in a
derived type when the parameter
signature of the derived method
differs only by types that are more
weakly derived than the corresponding
types in the parameter signature of
the base method.
EDIT
Basically you're hiding the base method (public bool Contains in Set), which will never now be run in preference to the derived method. But the derived method is more weakly defined than the base method so there are situations when the base method is the preferable method.

Resources