Convert Request Function to Generic Type

Convert request Function to Generic type

According to my comment I recommend to use a protocol with extension for example

protocol Fetchable
{
associatedtype FetchableType: NSManagedObject = Self

static var entityName : String { get }
static var managedObjectContext : NSManagedObjectContext { get }
static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
}

extension Fetchable where Self : NSManagedObject, FetchableType == Self
{
static var entityName : String {
return NSStringFromClass(self).components(separatedBy: ".").last!
}

static var managedObjectContext : NSManagedObjectContext {
return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
}

static func objects(for predicate: NSPredicate?) throws -> [FetchableType]
{
let request = NSFetchRequest<FetchableType>(entityName: entityName)
request.predicate = predicate
return try managedObjectContext.fetch(request)
}
}

Change (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext to the reference to your managed object context.

Make all NSManagedObject subclasses adopt Fetchable. There is no extra code needed in the subclasses.

Now you can get the data with

do {
let predicate = NSPredicate(format: ...
let objects = try MyEntity.objects(for: predicate)
} catch {
print(error)
}

That's all, objects are [MyEntity] without any type casting and always non-optional on success.

The protocol is easily extendable by default sorting descriptors, sorting directions etc.

Java 7: Generic method to convert GET response to Generic Object

You need only to pass a Class<T> parameter.

Note that you don't need a cast on the readValue method response because you already passed clazz as parameter so it returns a clazz element.

Your error was only that you assigned the result to an object of type Object. Than returned it. Remove the not necessary assignement and return directly from the result of the call to readValue.

public static <T> T getForEntity(String url, Class<T> clazz)  throws InterruptedException, 
ExecutionException, IOException {
Response getResponse = callWithHttpGet(url);
String getResponseJson = getResponse.getBody();
ObjectMapper getResponseJsonMapper = new ObjectMapper();
return getResponseJsonMapper.readValue(getResponseJson, clazz);
}

Generic type conversion FROM string

I am not sure whether I understood your intentions correctly, but let's see if this one helps.

public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
set { base.Value = value.ToString();}
}
}

Generics - Use return type of a parameter function as return type

Unfortunately, TypeScript does not support partial type parameter inference (see microsoft/TypeScript#26242 for discussion). Right now it's all or nothing: either you let the compiler infer all of your type parameters, or you specify all of them. (It might seem like generic parameter defaults could do this for you since it lets you specify just some of the parameters; but the unspecified parameters are not inferred, but take on the default value. Which is not what you want.)

Until and unless microsoft/TypeScript#26242 gets implemented in some way, there are only workarounds. The two workarounds I usually use are these:


CURRYING

Since you can't both specify and infer type parameters on the same generic function, you can split that single generic function into multiple functions, one of which you specify parameters and the other you let the compiler infer them for you. For example:

declare function useDataCurry<D>():
<R = D>(firstArg: object, fn?: TransformFn<D, R>) => R;

Here useDataCurry() is a function of no arguments that returns another function. The D (your Data) type parameter can be specified on useDataCurry(), and the R type parameter can be inferred on the returned second function. You could use it like this:

let data0 = useDataCurry<Response>()({ /*desc*/ }); // Response
let data1 = useDataCurry<Response>()({ /*desc*/ }, (res) => res.values); // string[]

This is almost exactly what you want, except that there's a weird-looking intervening function call.


DUMMYING

Another approach is to let the compiler infer all the type parameters, but you pass in a dummy argument of the type corresponding to the ones you'd like to specify. It doesn't even have to be a real value of the type; you can use a type assertion to make null look like the type you want.

For example:

declare function useDataDummy<D, R = D>(
dummyD: D, firstArg: object, fn?: TransformFn<D, R>): R;

The dummyD argument will be ignored in the implementation of the function, but it lets the compiler know what type you want for D:

let data2 = useDataDummy(null! as Response, { /*desc*/ }); // Response
let data3 = useDataDummy(null! as Response, { /*desc*/ }, res => res.values); // string[]

This is also almost exactly what you want, except that you are specifying the type argument as if it were a regular argument. Which is weird, but it works.


Either way works, but neither way is perfect. Oh well. Anyway, hope that helps; good luck!

Playground link to code

Proper way to cast object to generic type

My suggestion is to change method getValiable(String name). You can pass Class<T> varClass to this method. And your signature will be something like that:

<T> T getVariable(String name, Class<T> varClass);

If this method is placed in 3rd party library, I would recommend to you to create some wrapper for this class.

class Wrapper {
private OriginalClass originalObject;

<T> T getVariable(String name, Class<T> varClass) {
return (T) originalObject.getVariable(name);
}
}

Cast Object to Generic Type for returning

You have to use a Class instance because of the generic type erasure during compilation.

public static <T> T convertInstanceOfObject(Object o, Class<T> clazz) {
try {
return clazz.cast(o);
} catch(ClassCastException e) {
return null;
}
}

The declaration of that method is:

public T cast(Object o)

This can also be used for array types. It would look like this:

final Class<int[]> intArrayType = int[].class;
final Object someObject = new int[]{1,2,3};
final int[] instance = convertInstanceOfObject(someObject, intArrayType);

Note that when someObject is passed to convertToInstanceOfObject it has the compile time type Object.

How do I make the return type of a method generic?

You need to make it a generic method, like this:

public static T ConfigSetting<T>(string settingName)
{
return /* code to convert the setting to T... */
}

But the caller will have to specify the type they expect. You could then potentially use Convert.ChangeType, assuming that all the relevant types are supported:

public static T ConfigSetting<T>(string settingName)
{
object value = ConfigurationManager.AppSettings[settingName];
return (T) Convert.ChangeType(value, typeof(T));
}

I'm not entirely convinced that all this is a good idea, mind you...



Related Topics



Leave a reply



Submit