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
Related
This question already has answers here:
How can I return an anonymous type from a method?
(4 answers)
Closed 9 years ago.
I have some sub queries which are of data type var. These are getting working on a data table. I would like to pass these into another method, how can i do that?
Ex:
var subquery1= from results in table.AsEnumerable()
where //some condition
select new
{
column1=results.field1,
column2 = results.field2
etc.,
}
var subquery2= from results in table.AsEnumerable()
where //different condition
select new
{
column1=results.field1,
column2 = results.field2
etc.,
}
Now, I would like to define some method to pass these subquery1, subquery2 as variables.
ex:
void updategrid(var queries)
{
//some logic
}
And execute the method:
updategrid(subquery1);
updategrid(subquery2);
When i try to use var in the method when defining it is not liking it. Please help me in how to do that.
Thanks.
Your result is a sequence of anonymous objects. var Keyword is just saying to compiler "Hey, deduce arguments for me from usage". The process of deducing types from usage is called Type Inference. But you can't say to C# compiler to infer types of method arguments in method declaration. Moreover, in case of anonymous objects you cant specify their name. So you shouldn't pass them around outside and inside other methods. You can cast them to dynamic and then access their members via CallSite (compiler creates them when you access a member of dynamic object like myDynamic.Name) or you can cast anonymous object to object and access its properties via reflection, but all these methods are non C# idiomatic and really miss the point of anonymous objects.
Instead of creating anonymous objects in query
select new
{
//members selection
}
Create a custom type
public class Result
{
//Members declaration
}
And instantiate it as the result of query like in next example: (you can substitute var keyword instead of IEnumerable<Result> - compiled code will be the same)
IEnumerable<Result> subquery1 = from results in table.AsEnumerable()
where //some condition
select new Result
{
//fill members here
}
Method will look like
void updategrid(IEnumerable<Result> queries)
{
//some logic here with strongly typed sequence
}
Then you will call updategrid like simply updategrid(subquery1) and you will have all the beauty of statically typed sequence of your elements in the body of updategrid
You can declare method with var type of argument. But you can write so:
static void updategrid(dynamic queries)
{
}
var means take type from right-hand side and declare variable with this type from left-hand side and this is processed in compile-time. As you can seen using var as method argument type makes no sense.
void updategrid(var queries)
Is not valid C#.
var is syntactic sugar - the variable has a type, but you don't need to declare it if the compiler can statically determine what it should be.
With a parameter, the compiler doesn't have enough information to determine the type.
Similarly, you can't declare a variable with var without assignment:
var something;
You will need to ensure the types of subquery1, subquery2 and the parameter to updategrid are all the same.
Var is not a data type. It is short hand for "figure out what data type this actually is when you compile the app". You can figure out what the data type actually is and use that for your parameter or you could create a generic function that will work with any data type.
Use Object or dynamic
void updategrid(object queries)
void updategrid(dynamic queries)
var -> static type that is determined by the right side of expression. Cannot be used as parameter/return type
object -> Base class for all .NET types.
dynamic -> The type is resolved at runtime. Hence compile time checks are not made, and intellisense is not available. It has performance cost also.
In C#, there is no 'var' type. 'var' is just a keyword that tells the compiler to 'analyse whatever comes next to find out the type'. This is done during compilation, not runtime.
The variables you speak of are actually typed as anonymous types that the compiler automatically generates during compilation. Such types, since they have no name, cannot be used to declare parameter types or return values.
You should either create explicit classes for this data, or in .Net4 or later use the Tuple<> generic type.
You could probably use a dynamic reference, but I wouldn't go for that.
Instead, the better option is to create actual classes for those data types and pass them to the methods instead.
For example:
public class MyColumns
{
public string column1 {get;set;}
public string column1 {get;set;}
//etc.
}
Which you can create like this:
var subquery1= from results in table.AsEnumerable()
where //some condition
select new MyColumns
{
column1=results.field1,
column2 = results.field2
//etc.
};
and have a function like this:
public void updategrid(IEnumerable<MyColumns> queries)
{
}
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);
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());
I wanted to use something like this:
if(x==5)
{
var mydb= ........ ;
}
else
{
var mydb = ........ ;
}
but it didn't work because I can't declare a variable inside if statement.
So I tried to do this:
var mydb;
if (x==5)
{
mydb= ............. ;
}
else
{
mydb=.............;
}
but id didn't work either because I had to initialize the variable (mydb).
So the question is: I don't necessarily know the type of the variable, can I declare it anyway and then change the type inside the if statement?
No, you can't. Variables never change their types. What types are you actually interested in? Could you declare the variable to be some common base type or an interface that both of them implement? If you can tell us more about your situation, we may be able to help you more.
C# is a statically typed language (leaving aside C# 4; that introduces dynamic typing where you really need it, but it's worth understanding the "normal" C# way of doing things first). The compiler needs to know the type of the variable so that if can work out what each reference to it means. For example, if you use
string x = "text";
int y = x.Length;
the compiler needs to know that x is of type string so that it can check that the type has a Length property and emit a call to it in the IL.
you can use:
object mydb = null;
if(x==5)
{
mydb= ........ ;
}
else
{
mydb = ........ ;
}
but you have to unbox or cast the object back to its proper type when you want to access the object's fields,properties,methods. unless you will wait for C# 4 which can facilitate dynamic method (exact terminology: dynamic dispatch?) invocation
C# is statically typed unless you're running 4.0 with the dynamic specifier, so changing the type is classically impossible except via polymorphism.
You can declare base type and inherit both types from it. But the main question is:
How you gonna use it if you don't know its type?
I assume that you have two incompatible types from two different libraries that both represent a database. You could write an interface with the common operations and write adapters that wrap the classes coming from the libraries and implement you interface. Than the type of your variable mydb could be that interface.
Of course you could use objectas type for mydb and use dynamic type tests and casts, but that would be a very bad design decision in this case.
YOU CAN USE SYSTEM.CONVERT CLASS LIKE THIS OR USE DYNAMIC
string possibleInt = "1234";
int count = Convert.ToInt32(possibleInt);
OR USE Explicit Conversions
In C#, you can use a cast operator to perform explicit conversions. A cast specifies the type to convert to, in round brackets. The syntax for performing an explicit conversion is shown in the following code example.
DataType variableName1 = (castDataType) variableName2;
You can use like this
bool result = (condition) ? true : false ;
var myDB = (x==5) ? true : false ;
or
var myDB = x==5 ? "doing something when case is true" : "doing something when case is false" ;
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What’s the point of the var keyword?
What is the var type and should it be used in c#? When should it be used?
Can you specify the var type for the parameters to a method?
var is not a type. It is a convinient short hand notation that saves you a lot of typing. The following two declarations are equivalent:
Dictionary<string,List<int>> dic = new Dictionary<string,List<int>>();
and
var dic = new Dictionary<string,List<int>>();
As you can see, this saves typing and are easier to read. And if you descide to change the data type, you only have to change the right hand part.
But where I really like it most is in foreach loops:
foreach ( var item in someList )
Here item automatically takes the correct type, depending on the type of someList and it enables you to change the type of someList without haveing to change the declaration of item.
In short: var is GREAT and should be used.
EDIT: No, you can not specify var as a parameter to a function. The closest you can get to that is generics, I guess. And I also completely forgot to mention anonymous types. With those you have to use var.
It is part of the language, so yes, it should be used. It is not a type, however, but signifies a placeholder for the actual type determined by the compiler.
When should you use it? This has been asked before, many times:
Use of var keyword in C#
https://stackoverflow.com/questions/633474/c-do-you-use-var
var is not a type, it's an instruction to the compiler to let it figure out the correct type to use.
This means there is no difference at all to the output of the following two lines:
var s = "Test";
string s = "Test";
As for when to use it, you'll have to come up with your own rules. There is very few things you can do with var that you cannot do with a specific type name, but there is one thing: anonymous types.
You can do:
var x = new { A = 10 };
but you cannot come up with a strong type for that, since it has no type known at compile-time, instead the compiler will create the type during compilation, and then var will use that type.
That's what var was created to support, that it can also be used without anonymous types is a bonus, but you'll have to make up your own rules for when to use it in those cases.
Personally I only use it when the type is easily read from the source code, so I would use it for:
var dict = new Dictionary<int, string>();
var stream = new FileStream(...);
but not for:
var dict = GetDataStructure();
var stream = OpenFileForReading();
We tend to use it when interacting with all of our home grown libraries.
This is because we often change things as we are developing the libraries and quite often changing the type name or return type won't actually break the things which are using it.
We also tend to use it most of the time with the .NET framework as well.
However, we have put in an outright ban on using it with native types like int, string, bool etc. because it is not always clear what type the variable is in those cases.
Well, as mentioned earlier var is a short notation for a type name of any variable. As for me, I find, that var is overused by many developers and I think var makes code less readable sometimes. But one case where u should use it definitely is anonimous type variables.
Just to add to the other commentary, I suggest using var only when you can infer the type just by reading the code
var x = new Widget(); //ok
var y = Customer.Create(); // ok
var z = DoSomething(); //not ok
Some of the answers introduce Anonymous Types.
The var keyword on MSDN.
Know that var is not a type but a placeholder and can only be used within methods or properties (local variable definition). You can't use it in local member definition (private members of a class), neither can you when defining a method that should return whatever type, as generics, where you can use whatever name, except var (or any other reserved keyword) like so:
public IList<var> GetItems() { // Here the compiler will complain about the context of using `var` keyword within a local variable definition only.
}
public IList<T> GetItems() { // Here, we're talking about generics.
}
So, here are the principal rules to follow using the var keyword:
Local variable definition only;
Use var with anonymous types (Linq query, for instance);
Not to be confused with generic types;