I am trying to call a class method dynamically depending on a condition. This is how I am doing it
I have three classes implement a single interface
interface IReadFile
{
string DoStuff();
}
The three classes A,B,C implement the interface above.
I am trying to add them to a hashtable with the code below
_HashT.Add("a", new classA());
_HashT.Add("b", new classB());
_HashT.Add("c", new classC());
This compiles fine, but gives a runtime error.{Object reference not set to an instance of an object.}
I was planning to return the correct class to the interface type depending on a parameter that matches the key value. say if I send in a. ClassA is returned to the interface type and the method is called.
IReadFile Obj = (IReadFile )_HashT["a"].GetType();
obj.DoStuff();
How do I correct the part above where the objects need to be added to the hashtable? Or do I need to use a different approach? All the classes are in the same assembly and namespace.
Thanks for your time.
As a guess, you have not instantiated your _HashT object.
You need somewhere in your code (declaration or constructor probably) to instantiate it:
HashTable _HashT = new HashTable();
If you do not do this, _HashT will be null and an attempt to add to it will fail with a NullReferenceException as you have been getting.
It appears you are seeing a NullReferenceException. Based on the limited code you provided I would say it is likely that the _HashT variable is not assigned. It could be possible that the exception is being generated from one of your class constructors as well.
If you use Dictionary<> you can use the following code to add and extract objects from the hashtable.
var hashtable = new Dictionary<IReadFile>();
hashtable.Add("a", new ClassA());
hashtable.Add("b", new ClassB());
hashtable.Add("c", new ClassC());
IReadFile obj = hashtable["a"];
obj.DoStuff();
Following your approach, you do not need to call GetType() on the value you pull out of _HashT. The value should already be an object of type IReadFile.
Why are you calling GetType? The IReadFile object is the thing you are putting in the hash. Casting a Type object into a IReadFile is not going to cast correctly.
Related
if class type list is there named
Collection<PurchaseOrderDetail> poDetails = new Collection<PurchaseOrderDetail>();
and another list with same type is there named _poH.PODetail
why _poH.PODetail = poDetails.ToList(); generates an error
Cannot implicitly convert type 'System.Collections.Generic.List'
to 'System.Collections.ObjectModel.Collection'
what is the solution for this, any explanation please.
All the reason behind the question is
_poH.PODetail = poDetails;
made poDetails.RemoveAt(Convert.ToInt32(e.RowIndex)); updates as well so I was searching for some thing like _poH.PODetail = poDetails.ToCollection();
According to the error message, _poH.PODetail is of type Collection, so assigning a list to it doesn’t work. But since poDetails is a collection itself, you can just assign it directly:
poH.PODetail = poDetails;
So you don’t actually need to call ToList() on it to convert it to a list.
There is no ToCollection method you could call on enumerables, but you could use the Collection constructor that takes a list to make it wrap that list and create a readonly collection:
new Collection(poDetails.ToList());
The short answer is simply that the ToList<T> extension returns an instance of List<T> class which, although similar, is not the same type as Collection<T>.
Basically this doesn't work for the same reasons you cannot set a string value to an integer variable.
One thing you can do though, is initializing the content of a new collection instance with an IList<T> instance. Therefore, the following should give you exactly what you want:
_poH.PODetail = new Collection(poDetails.ToList());
Also, as poke suggested, you might also want to assign the PODetail property with the poDetails variable itself.
_poH.PODetail = poDetails;
However, you must remember that Collection<T> is a reference type. This means that the objects in your collection won't be "copied" inside _poH.PODetail; instead, both poDetails and _poH.PODetail will be pointing to the exact same collection. Any changes done to one collection will automatically be reflected on the other.
In my code I have an interface - lets say its called InterfaceName and its implementation called InterfaceImpl. Now when I dynamically try to obtain the InterfaceImpl using the following code:
object obj = Activator.CreateInstance("ProjectName","ProjectName.Folder.InterfaceImpl");
InterfaceName in = (InterfaceName)obj; //Error pops up here
I get the following error
Unable to cast object of type 'System.Runtime.Remoting.ObjectHandle' to type 'ProjectName.Folder.InterfaceName'.
Any suggestions on what might be going wrong ?
If you read the documentation about the method you are calling, it returns
A handle that must be unwrapped to access the newly created instance.
Looking at the documentation of ObjectHandle, you simply call Unwrap() in order to get the instance of the type you are trying to create.
So, I guess your real issue is... Why?
This method is designed to be called in another AppDomain, and the handle returned back to the calling AppDomain, where the proxy to the instance is "unwrapped".
What? That doesn't explain why?
Only two types can cross an AppDomain barrier. Types that are serializable (of which copies are created), and types that extend MarshalByRefObject (of which proxies are created and passed). ObjectHandle extends MarshalByRefObject, and so can cross that AppDomain barrier, whereas the type which they are representing may not extend MBRO or be serializable. This method ensures you can get that type instance across the barrier, no matter what.
So, if you are just trying to instantiate a type, you might want to look at a different overload of CreateInstance. Or just unwrap the result.
var obj = Activator.CreateInstance("A","A.B.C") as ObjectHandle;
InterfaceName in = (InterfaceName)obj.Unwrap();
Is there way to typecast an object to some specific type at runtime? Is it possible at all?
public static void TryTypeCasting(object obj)
{
Type type = obj.GetType();
// Can I use this "type" variable somehow to typecast "obj" to its actual type?
}
I am using C# 4.0.
EDIT 1:
Thanks all for your inputs.
I may be trying to achieve something impossible. But I posted this question in order to get views of experts on this and to know if something like this is made achievable in C# 4.0.
Here is a real time problem:
In our product, our client side API (method) serializes instance of "some" class (say Employee) that derives from our entity class called Person. That serialized instance (i.e. string value) is sent to the server side API (a method which has responsibility to de-serialize string to appropriate class's instance) through some intermediate classes. So, on the server side, only thing that API gets is a string.
However while serializing, custom serializer always add fully qualified name of the class (whose instance is being serialized) as the first line of the resulting output. So on server side, while reading the first line, I know the class (i.e. Employee in this case) to which the string should be de-serialized.
Further, we call a web service method (which I am not allowed to change) that accepts an argument of type Person.
Now, after deserialization at this stage, I have an instance of Employee stored in a variable of type object. But even though instance is available, I cannot pass it as an argument until I typecast it to Employee. How can I achieve this?
Sample code is provided here:
public static void Deserialize(string serializedObject)
{
StringReader stringReader = new StringReader(serializedObject);
// Read the first line to know class and assembly details
string firstLine = stringReader.ReadLine();
string[] assemblyAndClassDetails = firstLine.Split(new[] { ',' }, StringSplitOptions.None);
string className = assemblyAndClassDetails[0];
string assemblyName = assemblyAndClassDetails[1];
// Remove the first line before passing it to the serializer
serializedObject = serializedObject.Remove(0, firstLine.Length);
// Know the type of the serialized instance
Type typeToBeDeserializedTo = Type.GetType(className);
DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeToBeDeserializedTo);
using(MemoryStream memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(serializedObject)))
{
memoryStream.Position = 0;
object deserializedObject = dataContractJsonSerializer.ReadObject(memoryStream);
// NOW I WANT TO call a method that accepts an argument of type `Person` How can I do this?
}
}
No, this is entirely impossible (unless of course the specific type is known at compile time, in which case you can e.g. hardcode a cast).
It could never be any other way, since type casting means that the compiler has full knowledge of what the type of the result is. How would it be possible for the compiler to have knowledge of something that can only be determined at runtime?
Whenever this question comes up (and it does every so often), the answer is "there is probably an appropriate solution for your situation that involve neither this hypothetical type of cast nor reflection". If you state your case in more detail we could suggest such a solution.
You can't do this at runtime, because you don't know the actual type of the object. This information is known only at runtime, not at compile-time.
Say you could assign your object to a variable of the correct type (which I'm not sure is possible), you still cannot write any code against it within the method, as the compiler will not know what the type is at compile time.
A few options would be:
declare overloads of your method that can deal with the possible types you would like to accept
try casting to the possible types within the method
if ((var t1 = obj As type1) != null)
Do something with t1
Use Generics
As other said, this is impossible.
But what about duck typing?
((dynamic)yourObject).SomeMethod();
Type checking is delayed to execution of the code.
Pay attention to the fact that duck typing in a strongly-typed language like C# should be used with caution and for a specific set of use cases. Don't replace strong typing by using dynamic keyword everywhere!
I have a Dictionary(TKey, TValue) like
Dictionary<int, ArrayList> Deduction_Employees =
new Dictionary<int, ArrayList>();
and later I add to that array list an anonymous type like this
var day_and_type = new {
TheDay = myDay,
EntranceOrExit = isEntranceDelay
};
Deduction_Employees[Employee_ID].Add(day_and_type);
Now how can I unbox that var and access those properties ??
First, you aren't unboxing the type. Anonymous types are reference types, not structures.
Even though you can technically create instances of the same type outside of the method they were declared in (as per section 7.5.10.6 of the C# 3.0 Language Specification, which states:
Within the same program, two anonymous
object initializers that specify a
sequence of properties of the same
names and compile-time types in the
same order will produce instances of
the same anonymous type.
) you have no way of getting the name of the type, which you need in order to perform the cast from Object back to the type you created. You would have to resort to a cast-by-example solution which is inherently flawed.
Cast-by-example is flawed because from a design standpoint, every single place you want to access the type outside the function it is declared (and still inside the same module), you have to effectively declare the type all over again.
It's a duplication of effort that leads to sloppy design and implementation.
If you are using .NET 4.0, then you could place the object instance in a dynamic variable. However, the major drawback is the lack of compile-time verification of member access. You could easily misspell the name of the member, and then you have a run-time error instead of a compile-time error.
Ultimately, if you find the need to use an anonymous type outside the method it is declared in, then the only good solution is to create a concrete type and substitute the anonymous type for the concrete type.
There are several ways.
Since the comments seems to indicate that I suggest you do this, let me make it clear: You should be creating a named type for your object since you intend to pass it around.
First, you can use Reflection, which another answer here has already pointed out.
Another way, which tricks .NET into giving you the right type is known as "cast by example", and it goes something like this: You need to pass your object through a generic method call, which will return the object as the right type, by inferring the right type to return.
For instance, try this:
private static T CastByExample<T>(T example, object value)
{
return (T)value;
}
and to use it:
var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);
for the two ?? spots, you just need to pass something fitting the data type for those properties, the values will not be used.
This exploits the fact that multiple anonymous types containing the exact same properties, of the same type, in the same order, in the same assembly, will map to the same single type.
However, by this time you should be creating a named type instead.
An anonymous type has method scope. To pass an anonymous type, or a collection that contains anonymous types, outside a method boundary, you must first cast the type to object. However, this defeats the strong typing of the anonymous type. If you must store your query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.
Source: http://msdn.microsoft.com/en-us/library/bb397696.aspx
No you can't. You can only access the properties by using reflection. The compiler has no way of knowing what the type was, and since it's an anonymous type, you can't cast it either.
If you are using .NET 1.x - 3.x, you must use reflection.
If you use .NET 4.0, you could use a dynamic type and call the expected properties.
In neither case do you need to unbox; that's for value types. Anonymous types are always reference types.
I'm getting a Type using Assembly class as follows:
var asm = Assembly.GetAssembly(typeof(MyAssembly));
var t=asm.GetType("FULLY QUALIFIED CLASS NAME", true, true);
Then I create object from this type:
var obj = Activator.CreateObject(t, new []{ params });
Now I want to convert or cast this object to a Generic object (actually SubSonic Active Record Object).
var record = (ActiveRecord<PUT SOMEHOW TYPE t HERE>)obj;
How can I accomplish this?
The point of static typing is that you know the type at compile time.
What do you expect the type of the record variable to be? The compiler needs to know - it can't wait until execution time.
What do you want to do with record anyway? If the real goal is to create an ActiveRecord<T> object but you don't need to know the T for any other operations, then you'll need to use reflection with Type.MakeGenericType or MethodInfo.MakeGenericMethod depending on the ActiveRecord API (which I'm not familiar with)... but you're not going to be able to use the result in a statically typed way (that depends on T) in the lines of code which follow.
Does ActiveRecord<T> implement a nongeneric interface? If so, that's what you'd usually use after constructing the relevant instance.
If you can provide a link to ActiveRecord<T> documentation to show how to construct an instance, I'm happy to write the reflection code for you...
your class must inherit ActiveRecord or by itself be ActiveRecord .
you are trying to cast a type into another object receving the fomer as varible:
Cat c = new Cat();
List<Cat> l = (List<Cat>) c; // error.