I am new here and this is my first post. I recently got into touch with Jackson and i would like to know if it's possible to get other values than string (or int) while serializing. Pleae be kind if I confuse parts of the terminus.
For example: I have enum
public static enum Type {A, B, C}
in a class like
public class MyClass{
private Type charCat;
public Type getCharCat(){
return this.charCat;
}
public void setCharCat(Type t){
this.charCat = t;
}
}
But if I create an Object (for example with charCat A) and write it into a file I get
...
charCat: "A"
...
How could i get
...
charCat: A
...
?
I tried several tips and solutions, but they did not work.
I am not sure exactly what you are asking for, but the only valid kind of JSON would be
{ "charCat" : "A" }
as all textual values MUST be enclosed in double-quotes. Only values that do not need that are numbers, boolean values (true and false) and null. So serializing value as
{ charCat : A }
would not be valid JSON; so there is no way to get such output.
Related
I can't seem to get this working, but I'd be surprised if it wasn't possible in Haxe.
I'm trying to pass a couple of Enum values defined in my game to a function, so that it can then concatenate them as String types and pass that to other functions.
Example:
// In a general Entity class:
public override function kill():Void {
messages.dispatchCombined(entityType, ListMessages.KILLED);
super.kill();
}
And in my Messages.hx class:
package common;
import msignal.Signal.Signal1;
/**
* A Message / Event class using Signals bound to String names.
* #author Pierre Chamberlain
*/
class Messages{
var _messages:MessagesDef;
public function new() {
_messages = new MessagesDef();
}
public function add(pType:String, pCallback:FuncDef) {
if (_messages[pType] == null) {
_messages[pType] = new Signal1<Dynamic>();
}
var signals = _messages[pType];
signals.add( pCallback );
}
public function dispatch(pType:String, pArg:Dynamic):Bool {
var signals = _messages[pType];
if (signals == null) return false;
signals.dispatch(pArg);
return true;
}
//Compiler doesn't like passing enums :(
public inline function addCombined(pSource:Enum, pEvent:Enum, pCallback:FuncDef) {
add( combine(pSource, pEvent), pCallback );
}
public inline function dispatchCombined(pSource:Enum, pEvent:Enum, pArg:Dynamic):Bool {
return dispatch( combine(pSource, pEvent), pArg);
}
//How can I just pass the enum "names" as strings?
static inline function combine(a:Enum, b:Enum):String {
return String(a) + ":" + String(b);
}
}
typedef MessagesDef = Map<String, Signal1<Dynamic>>;
typedef FuncDef = Dynamic->Void;
Note how addCombined, dispatchCombined and combine expect an "Enum" type, but in this case I'm not sure if Haxe actually expects the entire Enum "class" to be passed (ie: ListMessages instead of ListMessages.KILLED) or if a value should work. Anyways, compiler doesn't like it - so I'm assuming another special Type has to be used.
Is there another way to go about passing enums and resolving them to strings?
I think you need EnumValue as parameter type (if it is only for enum values), and use Std.String to convert to String values.
static inline function combine(a:EnumValue, b:EnumValue):String {
return Std.string(a) + ":" + Std.string(b);
}
Of course that can be written smaller using String interpolation:
static inline function combine(a:EnumValue, b:EnumValue):String {
return '$a:$b';
}
Of course that can be 'more dynamic' using type parameters:
static inline function combine<A, B>(a:A, b:B):String {
return '$a:$b';
}
There is totally no need to use Dynamic as suggested. If you use Dynamic, you basically turn off the type system.
live example:
http://try.haxe.org/#a8844
Use Dynamic instead of Enum or pass them as Strings right away since you can always convert to enum from String if you need it later.
Anyway pass the enum as enum:Dynamic and then call Std.string(enum);
EDIT: Using EnumValue is definitely better approach than Dynamic, I use Dynamic in these functions because I send more than just Enums there and I am not worried about type safety in that case.
I know i can do this via Generics, as below, but how do i build an Extension to return the parent type with using Generics?
Generic Extension signature:
public static TEnum FromString<TEnum>(this Enum par , string val ) where TEnum : Enum {
return (TEnum) Enum.Parse(par.GetType(), val);
}
Signature style, i know it wont work but kinda what im looking for.
public static this FromString(this Enum par , string val ) {
return Enum.Parse(par.GetType(), val);
}
basically i have a series of Enum's that are having their values parsed to string for one process and as a receiver i need to parse that string value to the Enum for validation. Ultimately if the string value is not a valid value in the Enumerator it will return a null, or default, value. Its the fact i need to be able to return the source Enumerator's type without having to do a generic.
If its not possible, thats kewl, just figured i would try to do it without generics and do it with the extension logic pattern.
The short answer is no, you need the Generics to return the correct type of the Enum.
Otherwise, you'll just have the basic Enum type and not the specific type of your enum.
What you can do is create an extension method like this:
public static Enum FromString(this Enum par, string val)
{
return (Enum) Enum.Parse(par.GetType(), val);
}
But as you can see, you'll get a type of 'Enum' not of your specific enum.
On the other hand:
Enum val = default(MyEnum).FromString("SomeEnumValue");
bool isEnum = val is MyEnum; // Returns True
As you can see val is of type MyEnum and isEnum returns true
This also works:
MyEnum val = (MyEnum)default(MyEnum).FromString("SomeEnumValue");
I got a class
public class ID_Name<T>
{
public ID_Name(T id)
{
this.ID = id;
}
public T ID { get; set; }
public string Name
{
get
{
return Helper.SomeReturnValue;
}
}
}
All I want to do is generate a custom List of ID_Name where I can pass an ID_Name.ID as parameter in Add.
I tried the following:
public class ID_Name_List<T> : IList<T> where T : ID_Name<T>
but then I get the following error:
The type "EProtokollStatus" cannot be used as type parameter "T" in
the generic type or method "ID_Name_List<\T>". There is no boxing
conversion or type parameter conversion from "EProtokollStatus" in
ID_Name<\EProtokollStatus>.
I read something about this issue here: No boxing or type parameter conversion for generic Type parameter but I can't see a restriction except ID_Name here.
This may be wrong somehow, because everything I want to express is "use the same type T as in ID_Name for ID_Name_List", but how do I achieve that?
I found something here: C#: Declaring and using a list of generic classes with different types, how? but I don't want to create many different classes for all possible types.
All I want to achieve is something like
ID_Name_List<EProtokollStatus> myList = new ID_Name_List<EProtokollStatus>();
myList.Add(EProtokollStatus.ValueX);
Your current constraint makes no sense. Did you mean:
public class ID_Name_List<T> : IList<ID_Name<T>>
Suppose I have a List<IMyInterface>...
I have three classes which implement IMyInterface: MyClass1, MyClass2, and MyClass3
I have a readonly Dictionary:
private static readonly Dictionary<Type, Type> DeclarationTypes = new Dictionary<Type, Type>
{
{ typeof(MyClass1), typeof(FunnyClass1) },
{ typeof(MyClass2), typeof(FunnyClass2) },
{ typeof(MyClass3), typeof(FunnyClass3) },
};
I have another interface, IFunnyInteface<T> where T : IMyInterface
I have a method:
public static IFunnyInterface<T> ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
IFunnyInterface<T> otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
I'm trying to call the constructor of FunnyClasses and insert as parameter my MyClass object. I don't want to know which object it is: I just want to instantiate some FunnyClass with MyClass as a parameter.
What happens when I call ConvertToFunnyClass, T is of type IMyInterface, and when I try to cast it to FunnyInterface<T>, it says I can't convert FunnyClass1, for instance, to FunnyInterface<IMyInterface>
My current workaround (not a beautiful one), is this:
public static dynamic ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
var otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
And I don't like it because the return type is dynamic, so when I access it from somewhere else, I have no idea what type it is, and I lose intellisense, and stuff. I don't know about any performance implications either.
Any clues?
Thanks in Advance!
Resolution
As I'm using C# 4.0, I could stop casting errors using covariance (output positions only), and so I changed my IFunnyInterface to
IFunnyInteface<out T> where T : IMyInterface
Thank you all for the replies.
Essentially, your problem is that you are trying to convert FunnyInterface<T> to FunnyInterface<IMyInterface>. As has been mentioned several times (one example is here, more information here), this is not valid in most circumstances. Only in .NET 4, when the generic type is an interface or delegate, and the type parameter has been explicitly declared as variant with in or out, can you perform this conversion.
Is FunnyInterface actually an interface?
thecoop answer points you exactly to why you can't do it.
A cleaner solution to the problem (besides using dynamic) would be a base non-Generics Interface:
public interface IFunnyInterfaceBase
{
}
public interface IFunnyInteface<T> : IFunnyInterfaceBase
where T : IMyInterface
{
}
And you need to move methods signature you use in that code from IFunnyInteface to IFunnyInterfaceBase.
This way you would be able to write something like this:
MyClass2 c2 = new MyClass2();
IFunnyInterfaceBase funnyInstance = c2.ConvertToFunnyClass();
The Exception you said you got in your code is not due to the extension method signature itself (the method is fine)..it is originated by the type of your lvalue (the type of the variable you use to store its return value)!
Obviously this solution applies only if you can modify IFunnyInterface source code!
I have a function that returns objects of different types based on the parameter passed to this function.
Is it possible to add these different object types to a collection based on some identifier in C# 4.0?
Usually we do something like this
List or List
but i want one collection which can add object of any type.
Instead of just making a List<object> like other posters are recommending, you may want to define an interface eg IListableObject that contains a few methods that your objects need to implement. This will make any code using these objects much easier to write and will guard against unwanted objects getting into the collection down the line.
Yes, it is called object. Eg:
var objlist = new List<object>();
objlist.Add(1);
objlist.Add(true);
objlist.Add("hello");
You could use object[], List<object>, ArrayList, IEnumerable, ... but if those types have a common base type it would be better to stick to a strongly typed collection.
Really your collection should be as specific as you can make it. When you say
objects of different types
Do these objects have anything in common? Do they implement a common interface?
If so you you can specialise the list on that interface List<IMyInterface>
Otherwise List<object> will do what you want.
Update
No, not really.
I'm sorry but I'm going to question your design.
If you have a collection of different objects, how do you decide how to use one of the objects?
You're going to have a large switch statement switching on the type of the object, then you cast to a specific object and use it.
You also have have a similar switch statement in your factory method that creates the object.
One of the benefits of Object Orientation is that if you design your objects correctly then you don't need to do these large "If it's this object do this.Method(), if it's that object do that.OtherMethod()".
Can I ask, why are you putting different objects into the same collection? What's the benefit to you?
If you want a collection which can add objects of any type then List<object> is the most appropriate type.
Collections in earlier versions of C# (not generics) can contain any kind of objects. If they're value type, they will be boxed into object.
When you need to use them, you can just cast it to the original type.
You may use List<Type> to hold the type information, if that's what you want. And Type[], Hashtable, etc. are also fine. You can use typeof operator to get the type or use Object.GetType().
Also check out Dynamic type.
http://msdn.microsoft.com/en-us/library/dd264736.aspx
It will basically do the same thing.
My Suggestion:
public class ParamValue
{
object value = null;
public ParamValue(object val)
{
value = val;
}
public string AsString()
{
return value.ToString();
}
public int AsInt()
{
return int.Parse(value.ToString());
}
public int? AsNullableInt()
{
int n;
if (int.TryParse(value.ToString(), out n))
{
return n;
}
return null;
}
public bool AsBool()
{
return bool.Parse(value.ToString());
}
public bool? AsNullableBool()
{
bool b;
if (bool.TryParse(value.ToString(), out b))
{
return b;
}
return null;
}
}
public class Params
{
Dictionary<string, object> paramCol = new Dictionary<string, object>();
public void Add(string paramName, object value)
{
paramCol.Add(paramName, value);
}
public ParamValue this[string paramName]
{
get
{
object v;
if (paramCol.TryGetValue(paramName, out v))
{
return new ParamValue(v);
}
return null;
}
}
}
Use param class as a collectio to your values, you can convert the return to every type you want.
You could use a Tuple of Genric Types
public Tuple<T, T> MySuperMethod()
{
int number = 1;
string text = "Batman";
return new Tuple<int, string>(number, text);
}
The .NET Framework directly supports tuples with one to seven
elements. In addition, you can create tuples of eight or more elements
by nesting tuple objects in the Rest property of a Tuple object.
https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.100).aspx