Check if type is derived from another type - typewriter

I want to check if the current property type is derived from another type
string TypeConverter(Type type)
{
if(type.??.IsAssignableFrom(typeof(Entity)))
}
How do I get C# type object of the CodeModel.Type??

You don't have access to the full C# reflection system in Typewriter templates so you'll have to use a more primitive approach. Try something like this:
string TypeConverter(Type type)
{
if(type.BaseClass?.Name == "Entity")
{
...
}
}

Related

How to define nullable types if nested types are not supported

I'm using a component and one of the properties is of type System.Type. This works fine in most cases but now I find myself in need of int?. This didn't seem quite straightforward and after some searching and trial and error I ended up with this:
<local:NullableUInt32PropertyEditor PropertyType="{x:Type system:Nullable`1[System.UInt32]}"/>
This compiles and works as it should but the Error list gives
Nested types are not supported: Nullable`1[System.UInt32].
Intellisense also give a squigly line under the statement and the preview also states invallid markup.
What is the correct way to handle this?
thank you,
Jef
Edit: this is not the same as declaring a value as in this question (Declare a Nullable int (int?) using XAML). I need to declare the type, not a value.
After some further research I came up with this solution:
public class NullableExtension : TypeExtension
{
public NullableExtension()
{
}
public NullableExtension(string type)
: base(type)
{
}
public NullableExtension(Type type)
: base(type)
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
Type basis = (Type)base.ProvideValue(serviceProvider);
return typeof(Nullable<>).MakeGenericType(basis);
}
}
and then in xaml:
<local:NullableUInt32PropertyEditor PropertyType="{local:Nullable system:UInt32}"/>

How do I get array item type in TypeScript using the Reflection API?

I have the following little class in TypeScript, with some public fields decorated:
class Company {
#dataMember
public name: string;
#dataMember
public people: Person[];
}
class Person {
// ...
}
By using reflect metadata, I can determine the types of Company properties name and people: they are the constructor functions String and Array, respectively, which is expected and logical.
My property decorator function:
function decorate(target: Object, propertyKey: string | symbol): void {
var reflectType = Reflect.getMetadata("design:type", target, propertyKey);
// ...
}
But how could I determine the type (constructor function) of array elements? Is it even possible? In the above example, it should be (a reference to) Person.
Note: I need the type reference before instantiation, and because of this, it is impossible to dynamically determine the type using array items: there are no array items, there isn't even an Array instance.
I don't think this is possible as of now. If you see the generated js file, for array of anything, it creates metadata with type as Array without any information on type.
__decorate([
dataMember_1.dataMember,
__metadata('design:type', Array)
], Company.prototype, "people", void 0);
For built-in types, one way I could think of solving this problem is to pass the type in the decorator itself and writing the custom logic in the decorator code.
#dataMember(String)
myProp: Array<String>
For Custom objects, most of the time when the decorator call is fired, the module is not fully loaded. So, one way is to pass the class name and parse it later.
#dataMember("People")
people: People[]

VAADIN: Why I can't set a converter to a ComboBox?

I've made a converter:
public class BooleanToDateConverter implements Converter<Boolean, Date> {
private static final long serialVersionUID = 1L;
#Override
public Date convertToModel(Boolean value, Class<? extends Date> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == true) {
return new Date();
} else {
return null;
}
}
#Override
public Boolean convertToPresentation(Date value, Class<? extends Boolean> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
if (value == null) {
return false;
} else {
return true;
}
}
#Override
public Class<Date> getModelType() {
return Date.class;
}
#Override
public Class<Boolean> getPresentationType() {
return Boolean.class;
}
}
Then I have a Vaadin ComboBox myComboBox
I try to set my converter to it:
myComboBox.setConverter(new BooleanToDateConverter());
Then I get an error in Eclipse saying:
The method setConverter(Class<?>) in the type AbstractField<Object> is not applicable for the arguments (BooleanToDateConverter)
However, I've seen other converters being used similarly and they don't get errors. Why?
Your code cannot be compiled because there is no setConverter() method available on class ComboBox that fits your custom converter. Let me explain how converters are used on select components and what is the idea behind the specific method signatures you find for setting converters on a ComboBox.
ComboBox provides two overloaded versions of setConverter():
setConverter(Class<?> datamodelType): set a pre-registered converter for the given data model type
setConverter(Converter<Object, ?> converter): set a concrete converter instance
Both of these methods are actually inherited from class AbstractField<T> where T is the data type managed by the field (e.g. Strings for text fields, Date for a DateField, Object for ComboBoxes). A converter is typically used to convert between a presentation type (such as the textual representation of a value on the UI) and its internal model type (such as a date, a monetary value or a custom JavaBean). So, for instance, if you have a Label you can use a StringToDateConverter to correctly display a Date object, which has been set as the value of the Label, in a properly localized way.
How is that with select components such as ComboBox? Here the type T is Object. The data type of a select component actually represents the item ID of the selected item from the underlying container data source. So, if you use a BeanItemContainer as the data source of a ComboBox, the container's item IDs (and hence the selected value of the ComboBox) are the contained JavaBean objects themselves. The concrete type of the item IDs depends on the container implementation used. Therefore, select components are Field components with value type Object. In other words, select components use Object as presentation type.
That is why you can only set a converter instance on a select component whose generic PRESENTATION type is Object. The model type can be chosen freely. And this also explain why you can't set a converter with presentation type Boolean and model type Date on a ComboBox -- ComboBox doesn't use Boolean as presentation type.
I wrote a blog post about Vaadin FieldGroups which also provides a good example for a use case when to use a Converter<Object, ?> on a ComboBox. You can find this article at http://blog.oio.de/2014/04/25/select-nested-javabeans-vaadin-fieldgroup/.
I don't know what you want to achieve with your code, because a converter between a presentation type of Boolean and a model type of Date doesn't make much sense. I can only guess that you want to implementat some sort of decision logic, maybe to decide whether or not a date has been set? In that case you need to take a different approach.
For reference, have a look at the Book of Vaadin on Converters.

Databinding to an ObservableCollection of unknown object type

In my main project I have an ObservableCollection<DataValue>, where DataValue is a type from a 3rd party library, and it looks like this (simplified):
public class DataValue : IFormattable, ICloneable
{
private object m_value;
private TypeInfo m_typeInfo;
public object Value
{
get { return this.m_value; }
}
public TypeInfo TypeInfo
{
get
{
if (this.m_typeInfo == (TypeInfo) null)
return TypeInfo.Unknown;
else
return this.m_typeInfo;
}
}
}
In a different project in my solution I have a view and viewmodel to display the data in this collection, and it works fine when binding to a ListBox (it correctly displays the value, if the DataValue.Value is an integer, a byte[] or whatever), so it somehow figures out of the actual type automatically?
I want the same behavior in a custom control I have created, and if the value is a collection of byte[], it should process the data.
How can I accomplish this? I tried fooling around with a ValueConverter and some reflection and casting, but it seems unnecessary since the native controls seem to figure this out automatically.

What use has RoutedCommand' class constructor ownertype argument?

The constructor of the RoutedCommand has "owner type" as a last argument. What is its significance? When it is used?
MSDN documentation gives completely no clue about why it's needed and whether I could use one type for all commands
Quote from MSDN
ownerType
Type: System.Type The type
which is registering the command.
There is one more thing. What type should I use when creating new routed commands dynamically from array of names. It looks like that any type works, so I'm using UIElement, but if there is a more suited type for this I would like to know.
The source for RoutedCommand shows that the type becomes the OwnerType property. This property is queried ultimately by the following private method when getting InputGestures. So it looks as though this type is being used to lookup a (hard-coded) set of Commands based on the type that created the RoutedCommand.
private InputGestureCollection GetInputGestures()
{
if (this.OwnerType == typeof(ApplicationCommands))
{
return ApplicationCommands.LoadDefaultGestureFromResource(this._commandId);
}
if (this.OwnerType == typeof(NavigationCommands))
{
return NavigationCommands.LoadDefaultGestureFromResource(this._commandId);
}
if (this.OwnerType == typeof(MediaCommands))
{
return MediaCommands.LoadDefaultGestureFromResource(this._commandId);
}
if (this.OwnerType == typeof(ComponentCommands))
{
return ComponentCommands.LoadDefaultGestureFromResource(this._commandId);
}
return new InputGestureCollection();
}
I know this is a very old question, but it's the top search hit for "routedcommand ownertype".
Storing an OwnerType and Name within each RoutedCommand object gives you a hint on how to find references to it in code. Suppose you are running the debugger on some method that has an arbitrary ICommandSource parameter. You can examine the Command property, and if you see that OwnerType is CommonCommands and Name is "DoSomething", you can navigate to the DoSomething field of the CommonCommands class, where there might be a useful comment, or search for references to CommonCommands.DoSomething to find associated CommandBindings or something. Without those properties, the RoutedCommand would just be an anonymous object.
I don't know if that reason was what the API designers actually had in mind when they included the argument, but it has been useful to me at least.

Resources