3

I have a type like this:

public class TypeValue { public Type Type { get; private set; } public object Value { get; private set; } } 

so I can do something like:

TypeValue tv = ... int count = (tv.Type) tv.Value; 

but the compiler is giving me this error:

The type or namespace name 'tv' could not be found (are you missing a using directive or an assembly reference?)

How do I achieve this?

3
  • Thanks but why? Type isn't a keyword, right? Commented Feb 11, 2011 at 23:34
  • In your example you know that 'count' is an int because you just declared it. Commented Feb 11, 2011 at 23:41
  • Agreed there is that. I have to think about this but I might not need this kind of cast then. Although I am still surprised I couldn't do the above thing. For instance, how can I store "the int" so it could be placed in code like above? I guess that can't be done. Because if "(type) value" was using actual System.Type values then it would still work because it would be known at compile time, no? Commented Feb 11, 2011 at 23:52

4 Answers 4

3

No. How would the compiler be able to determine what type "Type" refers to at compile time? A "type" object is not the same thing as the name of a type that is used when performing a cast. For example, this doesn't work either:

// "typeof" returns a "Type" object. string foo = (typeof(string))SomeObj; 

You won't be able to use a static cast, but you can be sneaky and do this using reflection at runtime.

Sign up to request clarification or add additional context in comments.

7 Comments

Then how can I do runtime casts?
Actually, that was a bad example. Posted a different one.
Using C# dynamic might also be an option, depending on what Joan is trying to do with the cast value.
If I use dynamic, do I just change the object Value to dynamic Value?
Yes. It looks at the LHS: thus, string text = tv.Value; would attempt to cast to string, and int count = tv.Value; would attempt to cast to int. And you can catch RuntimeBinderException to handle where tv.Value wasn't the right type. Note this is a simple cast: it will NOT attempt to e.g. parse a string into an integer, or call ToString() if the target is a string, nor will it consider conversion operators.
|
3

Assignment you displayed cannot be done way you want. Types of objects on either sides of assignment operator must be equal (or right-hand object must be of type inheriting left-hand object type).

So, you cant do

Type1 obj1 = new Type1(); Type type = typeof(Type1); Type2 obj2 = (type)obj1; 

You could achieve functionality you want by making your class generic, or having a generic method for getting value. E.g.

public class TypeValue { public Type Type { get; private set; } public object Value { get; set; } public T GetValueAs<T>() { if (Value == null) return default(T); return (T)Value; } } TypeValue a = new TypeValue(); a.Value = 1; int b = a.GetValueAs<int>(); 

or even better

public class TypeValue<T> { public Type Type { get { return typeof(T); } } public T Value { get; set; } } TypeValue<int> a = new TypeValue<int>(); a.Value = 1; int b = a.Value; Type c = a.Type; 

1 Comment

+1 for second solution. First one is not a solution, he doesn't have type int with him. He needs to get it dynamically from TypeValue.Type property.
1

You should just do:

TypeValue tv = ... int count = (int) tv.Value; 

See, in the case where you know the type at compile-time (in this case you know that count is an int), then there's no point referring to tv.Type anyway. This helps illustrate why this doesn't make logical sense and thus is not possible.

2 Comments

The point is that the type of count is always known, even if the type of tv.Value is not. Thus you can use a static cast. If you do not even know the type of count, then this entire situation doesn't apply as you cannot really do anything with the object anyway except pass it to someone else... who will eventually do a cast when the type is assumed.
You are right. I was just trying to save the Type value so it might be used the way I posted above, but I guess there is no point for this.
1

It's impossible to get a strongly-typed variable from System.Type and System.Object. Sometimes you can make your class generic like this:

public class TypeValue<T> { public T Value { get; private set; } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.