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
How to Tap on a Specific Point Using Xcode Uitests
Undefined Symbols for Architecture I386: "_Objc_Class_$_Zipexception", Referenced From: Error
How to Use Call Directory Extension to Identify a Incoming Call in My Application
Xcode UI Testing Error Keyboard
Error: Cuicatalog: Invalid Asset Name Supplied: (Null), or Invalid Scale Factor:2.000000
How to Develop iPhone Mdm Server
Facebook Graph API Get Request - Should Contain "Fields" Parameter (Swift, Facebook Sdk V4.5.1)
How to Put the Uipagecontrol Element on Top of the Sliding Pages Within a Uipageviewcontroller
In Swiftui, How to Use Uihostingcontroller Inside an Uiview or as an Uiview
How to Get Managedobjectcontext for Viewcontroller Other Than Getting It from Appdelegate
Fbsdkloginmanager Loginwithpublishpermissions Always Returns Iscancelled=Yes
Confused About Orthographic Projection of Camera in Scenekit
How to Force an App to Change Language in iOS/Objective-C
Datefromstring Returns Nil for Some Values
Back Button Callback in Navigationcontroller in iOS
Arkit Hide Objects Behind Walls
How to Change the Color of an Uiimage
Warning: Output of Vertex Shader 'V_Gradient' Not Read by Fragment Shader