Variable of indeterminate type - c#

I have a class that contains a variable of indeterminate type, which must be overridden at runtime, how can I do this?
Sorry for the disgusting question(
Example:
public class MyClass
{
public e_Type TypeValue;
public (variable of indeterminate type) Value;
}
public enum e_Type
{
string, int, bool, byte
}
At runtime variable TypeValue should determine the type of variable Value

Depending on what you actually mean, you should use either var or dynamic.
The var keyword simply lets the compiler take care of deciding which type you are actually using. If the data you will be assigning is truly dynamic during runtime, it won't do you much good. You should mostly look at var as syntactic sugar (even if it at times can be very, very helpful sugar) - i.e. it just saves you typing.
The dynamic keyword lets you create an object that is truly dynamic, that is you will not get a compiler or runtime error no matter what you try to assign to it. The runtime errors will happen later down the road when you try to call on a property that doesn't exist on it. This is essentially you telling the compiler "Hey, look, just don't give me any fuss about this object, allow me to assign anything to it and call anything on it. If I mess up, it's my problem, not yours."
I think whenever you are thinking about using dynamic you should consider the problem at hand and see if it can be solved in a better way (interfaces, generics etc).

It sounds like you're really after generics:
class Foo<T>
{
public T Value { get; set; };
}
Then you can create instances for different types:
Foo<string> x = new Foo<string>();
x.Value = "fred";
Foo<int> y = new Foo<int>();
y.Value = 10;
This is still fixing the type at compile-time - but when the code using the type is compiled.
var is completely wrong here - var is just used for implicitly typed local variables. In particular, you can't apply it to fields.
It's possible that you want dynamic, but it's not really clear from your question at the moment.

I know that this must be done using the keyword var
Nope, that isn't what var does. There are 3 things that leap to mind that would work:
object; can store anything, but requires reflection to do anything useful
dynamic; a special-case of object, where the compiler performs voodoo such that obj.SomeMethod() (etc) is resolved at runtime
generics, i.e. have the class be SomeType<T>, with the variable typed as T; generic constraints can make this T more usable by declaring features (interfaces) that it must have

var has the purpose of referencing anything, not to declare anything. It's the other way around.
I acomplished this once leveraging the System.Dynamic.ExpandoObject (C# 4 only!), it allows for properties to be added at will without declaring them, and they will be resolved at runtime (it resembles how PHP treats objects and I'm a huge fan of it).
A quick example:
dynamic myObject = new ExpandoObject();
myObject.myProperty = "You can declare properties on-the-fly inside me !";
Console.WriteLine(myObject.myProperty);

Related

Can I treat a reference type as a value type here, or do I need to clone?

Consider the following method:
public (MySpecialType one, MySpecialType two) ReturnTwoSeparateObjects()
{
MySpecialType before = new MySpecialType();
MySpecialType after = before;
after.MyProperty = "A value";
return (before, after); // These will be the same object, pointless returning twice
}
This will return the same object, since the assignment of after is simply the same reference to the memory allocated for before. I understand that, but I want to return a representation of the object before and after a property was changed.
I know I can probably deep clone before using serialization or something, but it seems like a pretty heavy approach (I may be wrong on this, it's an assumption). Assuming I wanted to avoid a deep clone, is there some way to treat before as a value type here?
Well you don't need to use serialization, but you do need to create separate objects. Quite how deeply you need to clone will depend on the type - for example, you don't need to clone any immutable types. (The more immutability you can introduce into your code, the easier this becomes.)
There's no concept of "treating a reference type as a value type", but even if there were it would only naturally perform a shallow clone anyway, so you wouldn't be much better off.
With the advent of C# 9 you have the option to define the MySpecialType as record instead of class, and do this:
public (MySpecialType one, MySpecialType two) ReturnTwoSeparateObjects()
{
var before = new MySpecialType();
var after = before with { MyProperty = "A value" };
return (before, after);
}
The method will return two different references, representing different versions of the same entity.
The records are immutable by default, and they are intended to be used as such.

Cast dynamic to var

I have following code:
public class Processor
{
private Query _query =
new SpecificQuery1();
//OR
//new SpecificQuery2();
public void ProcessItem(dynamic dynamicResult)
{
//Can't use intellisense on dynamicResult
var staticResult = dynamicResult as _query.GetSomeType();//Can't do it :(
//Can use intellisense on staticResult
}
}
and, surprisingly, it doesn't compile. Is there any way I could cast dynamic into var? I know it sounds insane, but this part will be edited a lot and if someone changes the QueryImplementation, he has to also change type in ProcessItem(). I want to reduce the number of steps to 1 - simply replace the SpecificQuery() and the type will change by itself.
So let me rephrase. I'd like to know if there is some way how to use intellisense on dynamicResult(or some of it's cast) based on which constructor is assigned to base class Query.
Thanks
EDIT :
I'm sorry, I probably asked incorrectly. I understand what is dynamic and var.
I didn't intent to use intellisense on dynamic.
I didn't intent to really cast dynamic to var.
What I wanted to say is, that if I have compile-time knowledge of what type the dynamic will be (it is stored in Query implementation - it can be static, const whatever I want) - is there any way I can use this knowledge to enable intellisense in ProcessItem()?
The var contextual keyword is just syntactic sugar. There is no need to "cast" anything to it, as the variable declared with it is already strongly typed.
If the type of the result of the function is dynamic, so will the variable declared with var.
staticResult is of type dynamic:
var staticResult = dynamicResult;
You can't get intellisense on a dynamic type. If you know the type that you will get, then cast to it - that will give you access to intellisense.
var staticResult = (myType)dynamicResult;
Note that the above can easily cause runtime errors and exceptions that will crash the process.
Please see this SO answer which explains the difference between var and dynamic in detail, in light of your question you should know that the compiler will know the type of var at compile time whereas dynamic can only be determined at runtime; hence, you can't assign a type casted from dynamic (to be determined at runtime) to var (to be determined at compile time).
So, why not keep it dynamic?
No, you cannot do anything like that.
To begin with, you cannot cast something to var since var is not a type. Furthermore, casting can only be done to a type that is statically known; this means that the type you are casting to must be hardcoded, and cannot be the result of evaluating an expression (such as the method call _query.GetSomeType() in your example).
you could implement somethong like
public abstract class AbstractQuery
{
AbstractQuery Create(dynamic result);
}
public class SpecificQuery1 : AbstractQuery
{
new public SpecificQuery1 Create(dynamic result)
{
...
}
}
public void ProcessItem(dynamic dynamicResult)
{
var staticResult = _query.Create(dynamicResult);
}
to convert from a dynamic to a typed result

casting from a var type to a different class

casting a var type objects to array of a class.
in my example I can query from the table all elements. but the problem is when i cast it, it just doesnt cast all instances.
any help??
There's no such type as "a var type". A declaration using var just makes the compiler infer the type of the variable. It's still statically typed, and works as if you'd explicitly declared it - although it allows you to declare variables which use an anonymous type.
In your case we don't know what any of the methods involved do, which means we can't really tell what's going on. It sounds like Query is probably of type IEnumerable<AccessPointItem>. You'll need to express in code how to convert from an AccessPointItem to an AccessPoint.
A few points to note:
Your query expression is somewhat pointless - you probably just want to call tsvc.CreateQuery<AccessPointItem>()
Conventionally, local variables in C# use camel casing (starting with lower case letters) not Pascal case
You create an array for no purpose - why?
Select() will never return null, so you don't need to check for it
Calling Cast will attempt to just cast each AccessPointItem to AccessPoint... is that really what you intended?
It looks as though you're you're mixing up your classes AccessPoint and AccessPointItem. Try this:
public static AccessPoint[] getAllAps()
{
return tsvc.CreateQuery<AccessPoint>("AccessPointTable").ToArray();
}
or this:
public static AccessPointItem[] getAllAps()
{
return tsvc.CreateQuery<AccessPointItem>("AccessPointTable").ToArray();
}
There is something wrong with the types involved.
First you read AccessPointItem:
var Query = from APs in tsvc.CreateQuery<AccessPointItem>(...)
Then you try to cast it to AccessPoint:
return Query.Cast<AccessPoint>()
You're gonna need to implement some kind of conversion method in order for that to work (unfortunately I never did it myself, but from a quick Google run I see plenty of info about the subject is available). I'll give it a shot off the top of my head:
//inside AccessPointItem.cs
public static AccessPoint ToAccessPoint(this AccessPointItem item) // extension method looks good for the job
{
AccessPoint retObj = new AccessPoint();
// assign properties from 'item' to 'retObj'
return retObj;
}
//Usage example in your case
return Query.Select(singleAccessPointItem => singleAccessPointItem.ToAccessPoint());

Non-read only alternative to anonymous types

In C#, an anonymous type can be as follows:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
// Do stuff
}
}
However, the following will not compile:
method doStuff(){
var myVar = new {
a = false,
b = true
}
if (myVar.a)
{
myVar.b = true;
}
}
This is because myVar's fields are read-only and cannot be assigned to. It seems wanting to do something like the latter is fairly common; perhaps the best solution I've seen is to just define a struct outside the method.
However, is there really no other way to make the above block work? The reason it bothers me is, myVar is a local variable of this field, so it seems like it should only be referred to inside the method that uses it. Besides, needing to place the struct outside of the method can make the declaration of an object quite far from its use, especially in a long method.
Put in another way, is there an alternative to anonymous types which will allow me to define a "struct" like this (I realize struct exists in C# and must be defined outside of a method) without making it read-only? If no, is there something fundamentally wrong with wanting to do this, and should I be using a different approach?
No, you'll have to create your own class or struct to do this (preferrably a class if you want it to be mutable - mutable structs are horrible).
If you don't care about Equals/ToString/GetHashCode implementations, that's pretty easy:
public class MyClass {
public bool Foo { get; set; }
public bool Bar { get; set; }
}
(I'd still use properties rather than fields, for various reasons.)
Personally I usually find myself wanting an immutable type which I can pass between methods etc - I want a named version of the existing anonymous type feature...
Is there an alternative to anonymous types which will allow me to concisely define a simple "record" type like this without making it read-only?
No. You'll have to make a nominal type.
If no, is there something fundamentally wrong with wanting to do this?
No, it's a reasonable feature that we have considered before.
I note that in Visual Basic, anonymous types are mutable if you want them to be.
The only thing that is really "fundamentally wrong" about a mutable anonymous type is that it would be dangerous to use one as a hash key. We designed anonymous types with the assumptions that (1) you're going to use them as the keys in equijoins in LINQ query comprehensions, and (2) in LINQ-to-Objects and other implementations, joins will be implemented using hash tables. Therefore anonymous types should be useful as hash keys, and mutable hash keys are dangerous.
In Visual Basic, the GetHashCode implementation does not consume any information from mutable fields of anonymous types. Though that is a reasonable compromise, we simply decided that in C# the extra complexity wasn't worth the effort.
In C# 7 we can leverage named tuples to do the trick:
(bool a, bool b) myVar = (false, true);
if (myVar.a)
{
myVar.b = true;
}
You won't be able to get the nice initialization syntax but the ExpandoObject class introduced in .NET 4 would serve as a viable solution.
dynamic eo = new ExpandoObject();
eo.SomeIntValue = 5;
eo.SomeIntValue = 10; // works fine
For the above types of operation, you should define your own mutable STRUCT. Mutable structs may pose a headache for compiler writers like Eric Lippert, and there are some unfortunate limitations in how .net handles them, but nonetheless the semantics of mutable "Plain Old Data" structs (structs in which all fields are public, and the only public functions which write this are constructors, or are called exclusively from constructors) offer far clearer semantics than can be achieved via classes.
For example, consider the following:
struct Foo {
public int bar;
...other stuff;
}
int test(Action<Foo[]> proc1, Action<Foo> proc2)
{
foo myFoos[] = new Foo[100];
proc1(myFoos);
myFoos[4].bar = 9;
proc2(myFoos[4]); // Pass-by-value
return myFoos[4].bar;
}
Assuming there's no unsafe code and that the passed-in delegates can be called and will return in finite time, what will test() return? The fact that Foo is a struct with a public field bar is sufficient to answer the question: it will return 9, regardless of what else appears in the declaration of Foo, and regardless of what functions are passed in proc1 and proc2. If Foo were a class, one would have to examine every single Action<Foo[]> and Action<Foo> that exists, or will ever exist, to know what test() would return. Determining that Foo is a struct with public field bar seems much easier than examining all past and future functions that might get passed in.
Struct methods which modify this are handled particularly poorly in .net, so if one needs to use a method to modify a struct, it's almost certainly better to use one of these patterns:
myStruct = myStruct.ModifiedInSomeFashion(...); // Approach #1
myStructType.ModifyInSomeFashion(ref myStruct, ...); // Approach #2
than the pattern:
myStruct.ModifyInSomeFashion(...);
Provided one uses the above approach to struct-modifying patterns, however, mutable structs have the advantage of allowing code which is both more efficient and easier to read than immutable structs or immutable classes, and is much less trouble-prone than mutable classes. For things which represent an aggregation of values, with no identity outside the values they contain, mutable class types are often the worst possible representation.
I find it really annoying that you can't set anonymous properties as read/write as you can in VB - often I want to return data from a database using EF/LINQ projection, and then do some massaging of the data in c# that can't be done at the database for whatever reason. The easiest way to do this is to iterate over existing anonymous instances and update properties as you go. NOTE this is not so bad now in EF.Core, as you can mix db functions and .net functions in a single query finally.
My go-to workaround is to use reflection and will be frowned upon and down-voted but works; buyer beware if the underlying implementation changes and all your code breaks.
public static class AnonClassHelper {
public static void SetField<T>(object anonClass, string fieldName, T value) {
var field = anonClass.GetType().GetField($"<{fieldName}>i__Field", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
field.SetValue(anonClass, value);
}
}
// usage
AnonClassHelper.SetField(inst, nameof(inst.SomeField), newVal);
An alternative I have used when dealing with strings is to make properties of type StringBuilder, then these individual properties will be settable via the StringBuilder methods after you have an instance of your anonymous type.
I know it is really old question but how about replacing whole anonymous
object:
`
if (myVar.a)
{
myVar = new
{ a = false, b = true };
}
`

Does the new 'dynamic' C# 4.0 keyword deprecate the 'var' keyword?

When C# 4.0 comes out and we have the dynamic keyword as described in this excellent presentation by Anders Hejlsberg, (C# is evolving faster than I can keep up.. I didn't have much time to acquaint myself with the var keyword)
Would I still need the var keyword ? Is there anything that var can do.. that dynamic can't?
var x = SomeFunctionThatIKnowReturnsSomeKindOfList();
// do something with x
dynamic x = SomeFunctionThatIKnowReturnsSomeKindOfList();
// do something with x
No, they're very different.
var means "infer the type of the variable at compile-time" - but it's still entirely statically bound.
dynamic means "assume I can do anything I want with this variable" - i.e. the compiler doesn't know what operations are available, and the DLR will work out what the calls really mean at execution time.
I expect to use dynamic very rarely - only when I truly want dynamic behaviour:
var lets you catch typos etc at compile-time
statically bound code is always going to run faster than dynamically bound code (even if the difference becomes reasonably small)
statically bound code gives more compile-time support beyond just errors: you can find call hierarchies, refactoring will work better, Intellisense is available etc
Dynamic and var represent two completely different ideas.
var
Var essentially asks the compiler to figure out the type of the variable based on the expression on the right hand side of the assignment statement. The variable is then treated exactly as if it were explicitly declared as the type of the expression. For example the following two statements are equivalent
var a = "foo";
string a = "foo";
The key to take away here is that "var" is 100% type safe and is a compile time operation
dynamic
Dynamic is in many ways the exact opposite of var. Using dynamic is essentially eliminating all type safety for thet particular variable. It many ways it has no type. When you call a method or field on the variable, the determination on how to invoke that field occurs at runtime. For example
dynamic d = SomeOperation();
d.Foo(); // Will this fail or not? Won't know until you run the program
The key to take away here is that "dynamic" is not type safe and is a runtime operation
Yes you will still need var:
Var is a variable whose type will be inferred by the compiler.
dynamic will have its type assigned at runtime
So:
Var i = "Hello World"
will have its type inferred as a string type in doing so intellisence will give you all the methods that string can use like,
i.Split("/")
Where as:
dynamic i = "Hello World"
won't have its type inferred untill runtime because the complier dosn't know what type it is yet, but will still let you do:
i.Split("/")
but when it calls the method that you need it may fail because the type is wrong and the method isn't there.

Categories