Can you return an 'anonymous struct'? [duplicate] - c#

This question already has answers here:
Getting value from anonymous type? [duplicate]
(3 answers)
Closed 6 years ago.
This answer describes constructing 'an anonymous struct' in C#: Is there an equivalent C# syntax for C's inline anonymous struct definition?
var x = new { SomeField = 1, SomeOtherField = "Two" };
Is it valid to return this from a method to avoid having to define a struct explicitly? A comment on that answer says no, but that was 2011...

That's not a struct, it's an Anonymous Type in C# (which is actually implemented as a class by the compiler). An anonymous type is declared in local scope, and you cannot pass it as a strong typed class in C# because it is a compiler generated class. Your options are either to use object or dynamic as return types, but you still lose the underlying type.
To sum up your question, the answer is a simple "not the way you want it to work".

MSDN says:
Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object. The compiler provides a name for each anonymous type, although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type.
So you can return it as an object but afterwards you cannot do too much with them unless you use reflection or dynamics.
If your real intention is to return multiple values use the Tuple<...> type instead:
return Tuple.Create<int, string>(1, "Two");

Related

what is <T> in System.Span<T> in c#? [duplicate]

This question already has answers here:
What is the <T> in Cast<T>() or List<T> in C#
(2 answers)
Closed 2 years ago.
I'm new into c# and I see a lot of things like System.Span<T>, System.Memory<T>, Span<T>, Memory<T>, System.Collections.Generic.IEnumerable<T> etc. in the C# documentation.
Can somebody please explain what <T> is?
Any help is appreciated.
Check Generic Parameters
In a generic type or method definition, a type parameter is a placeholder for a specific type that a client specifies when they create an instance of the generic type. A generic class, such as GenericList<T> listed in Introduction to Generics, cannot be used as-is because it is not really a type; it is more like a blueprint for a type. To use GenericList<T>, client code must declare and instantiate a constructed type by specifying a type argument inside the angle brackets. The type argument for this particular class can be any type recognized by the compiler. Any number of constructed type instances can be created, each one using a different type argument, as follows:
For instance:
GenericList<float> list1 = new GenericList<float>();
GenericList<ExampleClass> list2 = new GenericList<ExampleClass>();
GenericList<ExampleStruct> list3 = new GenericList<ExampleStruct>();
In each of these instances of GenericList, every occurrence of T in the class is substituted at run time with the type argument. By means of this substitution, we have created three separate type-safe and efficient objects using a single class definition. For more information on how this substitution is performed by the CLR
In addition to the above, you can also have constraints about the type that T can be.

How can I cast an object using a known Type object? [duplicate]

This question already has answers here:
Casting a variable using a Type variable
(11 answers)
Closed 4 years ago.
I have a Type variable and I need to cast another object to it. (one which I know what the type is, but currently its an "object" type). I need to do this for reasons that aren't really important to the answer.
// Pseudocode
MyObjectClass myTypedVar = new MyObjectClass();
Type myKnownType = myTypedVar.GetType();
var anotherObject = (myKnownType) anObjectVarThatIsReallyMyObjectClass;
I've read this page Type Casting an Object using a "Type" Object in C# and I understand but I don't think it applies directly. I anticipate a solution using reflection, but I just haven't been able to figure it out myself.
If I understand you correctly, you could use the Convert.ChangeType method:
var anotherObject = Convert.ChangeType(anObjectVarThatIsReallyMyObjectClass, myKnownType);
You won't get any kind of compile-time checking when using a dynamic type like this though. Please refer to the following blog post for more information about this.
Generic type parameters and dynamic types in C#: https://blog.magnusmontin.net/2014/10/31/generic-type-parameters-and-dynamic-types-in-csharp/

Getting the type of Dynamic variable [duplicate]

This question already has answers here:
get the Type for a object declared dynamic
(2 answers)
Closed 8 years ago.
I am accessing a COM object and a method returns a dynamic variable. I do not have the implementation of the method that returns the dynamic variable and I need to cast it to the appropriate type so that I can use it in my class.
So I would like to know if there is a way to find the underlying type of a dynamic variable during runtime.
The dynamic variable is the value returning from a COM function so the UnWrap doesnt work and GetType() returns COMObject type.
thanks
If the object being returned can be one of many Types then you're best to keep using it as a dynamic and only trying to access methods and properties you know will exist (I'd expect the COM method to have some indication of how to use the dynamic it returns).
var canBeLiterallyAnything = ComMethod();
canbeLiterallyAnything.MethodDocsSayExists();
var propVal = canBeLiterallyAnything.SomeProperty;
Of course, if all of the possible Types all implement the same interface, you could cast to that interface.
var typeSafeReference = (ISharedInterface)canBeLiterallyAnything;
If you know that the COM method returns a specific Type but just don't know what that Type is then for the purpose of investigation you can call GetType() and either write it to console or set a breakpoint and inspect it. This will let you then update your code to include a cast to that Type (which would minimise the impact of the use of dynamic, but also introduce the risk of a bad cast if other Types can be returned).
var type = canBeLiterallyAnything.GetType();
// e.g. If the above returns a Type of 'SpecificType', then you can update code to
var typeSafeReference = (SpecificType)canBeLiterallyAnything;
It should be noted that the COM method might not return a concrete Type, it might be returning an anonymous object, in which case there is no casting you can do so you'll have to just keep using it as a dynamic and only access properties/methods you know exist.

Is a generic type MyType<,> actually a type? [duplicate]

This question already has answers here:
If A<T1,T2> is a template for actual type, then why is typeof(A<,>) allowed?
(3 answers)
Closed 9 years ago.
I have some confusion with this that arose from messing around with exporting generic types in MEF
I noticed:
new Dictionary<string,bool>().GetType() == typeof(Dictionary<,>)
false
new Dictionary<string,bool>().GetType().GetGenericTypeDefinition() == typeof(Dictionary<,>)
true
Yet Dictionary<,> itself is not considered a ‘type’ as this will actually generate a compile error:
new Dictionary<string,bool> as Dictionary<,>
Type expected
new Dictionary<string,bool> is Dictionary<,>
Type expected
So my question is, is Dictionary<,> actually a type? Does .NET treat generic types differently than non-generic types?
Now in MEF I can export a generic class as
[Export(typeof(MyGenericClass<,>))]
And this would satisfy an import requirement like
[Import]
public MyGenericClass<string, long> Instance { get; set; }
I'm confused about the type-system's rules here
See What exactly is an “open generic type”. What you are referring to is called an unbound generic type and is explained in the same post. An unbound generic type is actually a type, however it can only be used within a typeof() expression. Note: Unlike C# Java allows expressions like List<?>.
Yes, MyType<,> is a type.
It's a "open generic" Type, See What exactly is an "open generic type" in .NET?

Anonymous Types

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.

Categories

Resources