When I wanted a generic object extended from a class, in Java I used to write:
Class<AuthenticationProvider> c1;
What am I supposed to write in C# to do the same? How can I cast a Type Class Object in this format (a generic class extended from Authentication provider)?
Do you mean Type.MakeGenericType?
Edit:
Oops, I see what you mean now. No, you can't do this in C#, because System.Type is not a generic type! It contains information about a type, but there's nothing generic about it, so typeof(Foo) does not give you Type<Foo>.
I don't see why you'd need it either, though.
Related
The paper Valued Conversions by Kevlin Henney gives a motivation for a so-called variant value type functionality, as well as an outline of a C++ implementation. It is a good read and it covers exactly what I would like to have available in C#: a general type that can hold values of different value-types.
I have not been able to find anything like this in C# though. Somewhat similar questions on SO have unsatisfactory answers and comments like "this is probably not what you want". This surprises me because it looks like fairly commonly required functionality. Henney's C++ boost::any class is widely used.
Is it not possible to create this functionality in C#?
Edit: Responding to one of the answers, I do not think that generics will do the trick. Using a generic requires the developer to know what kind of value-type the Variant variable is holding, and that type becomes immutable for that particular Variant variable as well. But the Variant type I am talking about should be able to hold different types. For example, a function Variant ReadValue() could read an entry from a file, parse it, fill the Variant value accordingly and then return it. The caller does not know in advance what kind of type will be contained in the returned Variant.
This is what generics are for. List<T> where T is anything at all. Generics provide both compile-time and runtime type safety.
You could create your own generic type to store any value you want. You could also cast anything to object and pass it around as such.
You can also use generic constraints to limit your type, such as wanting to only have T be a reference type:
public MyClass<T> where T : class
Or a value type:
public MyClass<T> where T : struct
See more here: http://msdn.microsoft.com/en-us/library/d5x73970.aspx
You can look into using dynamic for this as well.
The dynamic type enables the operations in which it occurs to bypass compile-time type checking. Instead, these operations are resolved at run time.
Type dynamic behaves like type object in most circumstances. However, operations that contain expressions of type dynamic are not resolved or type checked by the compiler.
From what I understand, using any in C++ is same as using combination of object and ChangeType method in C# with exception of having nice syntax for autoconversion from and into the any type. And without limitation just for value types.
Henney's article is quite old (year 2000). In a live lesson (London DevWeek 2008) I remember him explaining low coupling and implementing towards abstractions (interfaces) for the OCP (Open-Closed Principle). He was quite fond of generics and more so generic interfaces. So conceptually it's most probably exactly what he has written about back then, albeit I must admit I didn't read the article. C# generics are even a bit more robust then C++ templates, you should look at Covariance and Contravariance in Generics.
On another note:
What you can't do with generics are variable arity templates, which have been available for C and C++.
.NET knows many ways to convert data types:
Convert-class;
Functions inside a type like (Try)Parse and ToString, etc.;
Implementation of interface IConvertable;
The TypeConverter;
The implicit and explicit conversion operator;
Am I missing another one?
So if am converting one datatype to another, I need to know both types and I need to know which conversion method to use. And this becomes pretty nasty if one of those two types (or both) is a generic type.
So my question is: I there is uniform (generic) way in .NET to convert one data type to another, which might use all the other limited methods?
A good, generic way to convert between types is with Convert.ChangeType. Here's an example of how you could use it to write a generic converting method:
public static TResult Convert<TResult>(IConvertible source)
{
return (TResult)System.Convert.ChangeType(source, typeof(TResult));
}
It, like other Convert methods, internally calls the IConvertible interface.
This will not make use of your other conversion options:
The most common I'd think would be ToString; for that, you could add a check to see if TResult is string and if so, (after appropriate null checks) simply call ToString on your input.
Using reflection you could check for:
the TypeConverterAttribute (TypeDescriptor.GetConverter seems to be the way to go from there)
(Try)Parse methods, (which you'd invoke), and
implicit/explicit conversion operators (the methods op_Implicit and op_Explicit, which you'd likewise invoke)
These are each fairly self-explanatory if you know a bit about reflection, but I could elaborate if any prove difficult.
You imply those are all the same
They are not
Pick the appropriate
Convert Class
Converts a base data type to another base data type.
Parse is from string
ToString is a to string
IConvertible Interface
Defines methods that convert the value of the implementing reference
or value type to a common language runtime type that has an equivalent
value.
TypeConverter Class
Provides a unified way of converting types of values to other types,
as well as for accessing standard values and subproperties.
Yes you need to know the type you are converting to.
And you should be aware if the type you are converting from.
With generics there is no built in.
At best you provide a method.
But why do you need to convert generics?
You seem to imply that more than one way is a bad thing.
For a single way then I like the answer from Tim S. +1
But that does not mean I would ever use it.
The are even more ways to get data from a SQL database.
Is that a bad thing?
here's the code,
Type tbn = Type.GetType(dii.DictionaryName);
DictionaryXmlInfo4BaseDictionary<tbn>.AddDictionaryXmlInfo((message));//error
You can't use generics like that. Generics are meant to be used for types known at compile time.
You can do it with reflection - getting the generic DictionaryXmlInfo4BaseDictionary type definition, creating the closed type using Type.MakeGenericType, then calling AddDictionaryXmlInfo on it again by reflection... but it's relatively painful.
You cannot use generics with a type that is known only at runtime. The DictionaryXmlInfo4BaseDictionary<T> type is generic and requires the T argument to be known at compile time if you want to use it.
You can't use an instance of a type as a generic parameter.
The generic parameter should be the whatever the base instance is, DictionaryXmlInfo4BaseDictionary<object> in the most generic case, but you probably want something further down the class hierarchy than that.
You can't use Type in that way, refactor DictionaryXmlInfo4BaseDictionary so it takes a Type paramater as part of the method e.g.
DictionaryXmlInfo4BaseDictionary.AddDictionaryXmlInfo(tbn, message);
This question gives me curiosity... When you want to define a type you must say GetType(Type) ex.: GetType(string), but ain't String a type itself?
Why do you need to use GetType in those situations? And, if the reason is because it is expecting a Type 'Type'... why isn't the conversion implicit... I mean, all the data is there...
What you're doing is getting a reference to the meta-data of the type ... it might be a little more obvious if you look at the C# version of the API, which is typeof(string) ... which returns a Type object with information about the string type.
You would generally do this when using reflection or other meta-programming techniques
string is type, int is type and Type is type and they are not the same. but about why there is no implicit conversion it's not recommended by MSDN:
By eliminating unnecessary casts,
implicit conversions can improve
source code readability. However,
because implicit conversions can occur
without the programmer's specifying
them, care must be taken to prevent
unpleasant surprises. In general,
implicit conversion operators should
never throw exceptions and never lose
information so that they can be used
safely without the programmer's
awareness. If a conversion operator
cannot meet those criteria, it should
be marked explicit.
Take attention to :
never lose information so that they
can be used safely without the
programmer's awareness
When you want to define a type you must say GetType(Type) ex.: GetType(string)...
That's not true. Every time you do any of the following
class MyClass
{
///...
}
class MyChildClass : MyClass
{
}
struct MyStruct
{
///...
}
you're defining a new type.
if the reason is because it is expecting a Type 'Type'... why isn't the conversion implicit... I mean, all the data is there...
One reason for this is polymorphism. For instance, if we were allowed to do the following:
MyChildClass x;
....GetType(x)
GetType(x) could return MyChildClass, MyClass, or Object, since x is really an instance of all of those types.
It's also worth noting that Type is itself a class (ie, it inherits from Object), so you can inherit from it. Although I'm not sure why you'd want to do this other than overriding the default reflection behavior (for instance, to hide the internals from prying eyes).
GetType(string) will return the same information. Look at it like you would a constant. The only other way to get the Type object that represents a string would be to instantiate the string object and call o.GetType(). Also, this is not possible for interfaces and abstract types.
If you want to know the runtime type of a variable, call the .GetType() method off of it, as the runtime type may not be the same as the declared type of the variable.
From the documentation:
The CTypeDynamic method applies dynamic conversions in accordance with the conversion semantics defined by the object itself. If a dynamic object inherits from DynamicObject, the CTypeDynamic method first attempts to perform the conversion by using a user-defined, static conversion. If the user-defined, static conversion fails, the CTypeDynamic method attempts to perform the conversion by using dynamic conversions. If a dynamic object implements IDynamicMetaObjectProvider, the CTypeDynamic method gives precedence to dynamic conversions over user-defined, static conversions.
Is there something in C# that does this? Or do I just have to import the VB library that has it.
If you use C# 4.0 then yes, called dynamic. Here is the link
You don't need to import the VB library for this.
If you override TryConvert in your DynamicObject-derived class, then C# allows you to implicitly call this via an implicit or explicit cast.
//explicit conversion
String myObject = (String)myDynObject;
//implicit conversion
String myObject = myDynObject;
VB.NET only supports explicit conversions. C# supports both implicit and explicit.
Here's the link to MSDN about this.
Hope this helps!
I'd guess first casting to dynamic and then to the target type should do the trick.
Dynamic is available in C# 4.0 / VS 2010
In C# 3.0 / VS2008 you probably can work around using expressions. If I recall correctly the "MiscUtil" library contains functions to use the conversion operators in their generic operator class.
Short answer
You don't need to import anything. Just use implicit and explicit C# conversion and the "dynamic" keyword. D Hoerster's answer is correct.
Long answer
C# has a separate type to treat dynamic objects - the type is "dynamic". But in VB there is no dedicated type for this, since the dynamic behavior is implemented through late binding. So, in VB the dynamic objects that need real dynamic binding are sometimes hard to distinguish from just "objects". CType handles conversions of "objects" to types. In most cases, it is fine. However, when you deal with implementations of IDynamicMetaObjectProvider interface, it may cause troubles. CType can't understand whether it deals with "object" or "dynamic object" - there is no syntax to distinguish one from another and CType doesn't want to call dynamic binders for all objects defined through the late binding. It assumes that all the objects it deals with are "objects", not "dynamic objects".
So you need to somehow let the compiler know that you are dealing with a dynamic object. Instead of creating the new "dynamic" type, the VB team decided to just add one more conversion function - CTypeDynamic. It explicitly tells the compiler that you are converting dynamic type to some other type (again, in C# you don't need this, since you already defined the object by using the dynamic keyword and the compiler already knows what it deals with).
The good illustration of the problem is DynamicObject.TryConvert method. Try to replace CTypeDynamic with CType in the VB example and you'll see an exception. Again, this is because CType knows nothing about dynamic runtime binder. But in C# the runtime binder is called for all objects defined by the dynamic keyword, so it doesn't need this special function.
The C# equivalent function to VB's CTypeDynamic() is Convert.ChangeType().
The change in name helps distinguish the C# function as being about setting a type conversion at runtime according to a type variable, rather than being about the dynamic type mechanism.
Convert.ChangeType
Returns an object of a specified type whose value is equivalent to a specified object.
Conversion.CTypeDynamic
Converts an object to the specified type.
...
The CTypeDynamic method converts the object passed as the Expression parameter to the type specified by the TargetType parameter. If the object is a dynamic object, the CTypeDynamic method applies available dynamic conversions.
...
CTypeDynamic method first attempts to perform the conversion by using
a user-defined, static conversion