How do I provide custom cast support for my class?
You would need to override the conversion operator, using either implicit
or explicit
depending on whether you want users to have to cast it or whether you want it to happen automagically. Generally, one direction will always work, that's where you use implicit
, and the other direction can sometimes fail, that's where you use explicit
.
The syntax is like this:
public static implicit operator dbInt64(Byte x)
{ return new dbInt64(x); }
or
public static explicit operator Int64(dbInt64 x)
{
if (!x.defined) throw new DataValueNullException();
return x.iVal;
}
For your example, say from your custom Type (MyType
--> byte[]
will always work):
public static implicit operator byte[] (MyType x)
{
byte[] ba = // put code here to convert x into a byte[]
return ba;
}
or
public static explicit operator MyType(byte[] x)
{
if (!CanConvert) throw new DataValueNullException();
// Factory to convert byte[] x into MyType
return MyType.Factory(x);
}
How do I provide custom cast between two classes with Type arguments in C#
Your problem is that you are not creating the correct view model.
public ActionResult Create(int id)
{
AnimalType t = DbContext.AnimalTypes.Find(id); // get AnimalType object from database
AnimalViewModel<Animal> model = new AnimalViewModel<Animal>()
{
Animal = (Animal)t.CreateInstance() // Returns a Tiger object cast to an Animal
};
return View(model);
}
What you need to do is get a handle on the correct ViewModel type and create an instance of that with the correct generic. An Animal will always be an Animal no matter if you set it to a tiger or anything else unless you cast it to what it is supposed to be or attempt to call everything dynamically.
The code below will actually create you an AnimalViewModel<Tiger>
instead of AnimalViewModel<Animal>
which is causing your issues.
public class AnimalViewModel<T> where T : Animal
{
public T Animal { get; set; }
public AnimalViewModel(T animal)
{
Animal = animal;
}
}
public ActionResult Create(int id)
{
AnimalType t = DbContext.AnimalTypes.Find(id); // get AnimalType object from database
Animal animal = (Animal)t.CreateInstance();
var animalViewModel =
Activator.CreateInstance(typeof(AnimalViewModel<>).MakeGenericType(animal.GetType()),
animal)
return View(animalViewModel);
}
How to write custom casting method in Java
You can't overload the cast operator. Java doesn't support it and probably never will.
To convert a single value to an instance of the desired class, we use static factory methods.
public static Person fromAge(int age) {
return new Person(age);
}
They often return a partially constructed object. In the snippet above, a newly constructed person has only age
set: other fields will have their default values.
To do the opposite, we use getters.
public int getAge() {
return age;
}
However, since
toString
is already there, it makes sense to add other data types as well.
toInt
makes no sense when it's applied to me (as an instance of the Person
class). It could be my height, my weight, my age, a number of times I went to a bathroom today, etc. I can't represent myself by one int number, neither can a large majority of classes.
On the other hand, toString
can do this job pretty well: I can give you (read return) a summary of my hobbies, my biometric information, even my picture. Or I can leave it to the default implementation, which still would satisfactorily represent an object.
How to make type cast for python custom class
As noted by Anand in comments, what you're looking for is object serialization and deserialization. One way to achieve this is through the pickle (or cPickle) module:
>>> import pickle
>>> class Example():
... def __init__(self, x):
... self.x = x
...
>>> a = Example('foo')
>>> astr = pickle.dumps(a) # (i__main__\nExample\np0\n(dp1\nS'x'\np2\nS'foo'\np3\nsb.
>>> b = pickle.loads(astr)
>>> b
<__main__.Example instance at 0x101c89ea8>
>>> b.x
'foo'
Note, however, that one gotcha in using the pickle module is dealing with implementation versions. As suggested in the Python docs, if you want an unpickled instance to automatically handle implementation versioning, you may want to add a version instance attribute and add a custom __setstate__ implementation: https://docs.python.org/2/library/pickle.html#object.setstate. Otherwise, the version of the object at serialization time will be exactly what you get at deserialization time, regardless of code changes made to the object itself.
Allow casting a string to my Class
It sounds like your user
variable is of type object
. You've only provided conversion support for the following scenarios:
string
⇒SystemUser
SystemUser
⇒string
While your user
variable might contain a reference to an instance of string
, it can't be implicitly downcast to string
.
string
(or any other type, for that matter) can be implicitly upcast to object
(since string is object
evaluates to true
), the converse is not possible. An object
instance can't be implicitly downcast to string
since object is string
evaluates to false
.
You can:
explicitly cast your
object
tostring
and then toSystemUser
, orobject user = GetStringRepresentingUser() ;
SystemUser instance = (SystemUser)(string)user ;change the data type of
user
tostring
string user = GetStringRepresentingUser() ;
SystemUser instance = (SystemUser)user ;
Edited to Note:
Adding overloads may help you here. You can do something like this:
public static SystemUser GetSystemUser( object o )
{
SystemUser instance ;
if ( o is string )
{
instance = GetSystemUser( (string) o ) ;
}
else
{
instance = (SystemUser) o ;
}
return instance ;
}
public static SystemUser GetSystemUser( string s )
{
return (SystemUser) s ;
}
You might also consider using the Parse()
`TryParse()` idiom:
public static SystemUser Parse( string s )
{
// parse the string and construct a SystemUser instance
// throw a suitable exception if the parse is unsuccessful
}
public static bool TryParse( string s , out SystemUser instance )
{
// as above, except no exception is thrown on error.
// instead, return true or false, setting instance to default(SystemUser) (null)
// if the conversion wasnt' possible.
}
Using Parse()
/TryParse()
is likely to get more easily understood as well.
Not matter how you do it, at some point you're going to have to look at your object
and check its type:
If its actually a string, excplicity downcast to
string
and deserialize (parse) it back into an instance of your class, or...If it's not a string, it must be an instance of your type: excplicity downcast it.
How to custom cast a list to a different type?
I managed to solve the problem by also implementing a conversion in the 'StudentView' class from 'StudentView' to 'Student' and then using Magnetron's solution.
So I implemented a conversion in the 'View' class. Why this is needed I have no idea, seems magical to me considering this conversion shouldn't be necessary for the conversion of 'Student' to 'StudentView'. Perhaps there is something written somewhere that a two way cast is required for some reason.
public class StudentView : ViewBase<Student>
{
// Removed for brevity
public static implicit operator Student(StudentView student)
{
return new Student(student);
}
}
Then updated the casting to be performed like so as highlighted by Magnetron:
public async Task OnGetAsync()
{
Student = await _context.Student.Select(x => (StudentView)x).ToListAsync();
}
I'd also like to highlight billybob's answer as he provided another correct way to solve the solution, I just chose a different way.
C#: Custom casting to a value type
You will have to overload the cast operator.
public class Foo
{
public Foo( double d )
{
this.X = d;
}
public double X
{
get;
private set;
}
public static implicit operator Foo( double d )
{
return new Foo (d);
}
public static explicit operator double( Foo f )
{
return f.X;
}
}
Related Topics
How to Find the State of Numlock, Capslock and Scrolllock in .Net
Server Execution Failed (Exception from Hresult: 0X80080005 (Co_E_Server_Exec_Failure))
How to Initialize a C# Dictionary with Values
Upload Files and JSON in ASP.NET Core Web API
Deserializing Xml to Objects in C#
Copy Rows from One Datatable to Another Datatable
How to Detect When a Windows Form Is Being Minimized
Render Razor View to String in ASP.NET Core
System.Drawing.Image to Stream C#
What Is the "Right" Way to Bring a Windows Forms Application to the Foreground
Set Default Global JSON Serializer Settings
Checking User Name or User Email Already Exists
Singleton by Jon Skeet Clarification
How to Access Configuration in Any Class in ASP.NET Core