views:

296

answers:

5

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?

+7  A: 

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.

Jon Skeet
http://msdn.microsoft.com/en-us/library/dd264736%28v=VS.100%29.aspx
drorhan
@drorhan: Yes, but that's almost certainly not the right solution here - I'd encourage C# beginners to steer *well* clear of dynamic typing until they're comfortable with "normal" (static) C#.
Jon Skeet
Maybe he object type can be help.http://msdn.microsoft.com/en-us/library/9kkx3h3c%28VS.80%29.aspx
drorhan
@drorhan: That's rarely the case; typically there will be some common base type or interface with the desired functionality. If the two types really have nothing in common, I'd question whether the same variable should really be used in both cases anyway.
Jon Skeet
If the two types really have nothing in common, I'd suggest using a discriminated union type, like Haskell's Either (http://hackage.haskell.org/packages/archive/base/4.2.0.0/doc/html/Data-Either.html), or F#'s series of Choice<'T1, 'T2> (http://msdn.microsoft.com/en-us/library/ee353439(VS.100).aspx), types. `Either<string, int>` makes things much more explicit than `object`.
Martinho Fernandes
+1  A: 

C# is statically typed unless you're running 4.0 with the dynamic specifier, so changing the type is classically impossible except via polymorphism.

Ignacio Vazquez-Abrams
Variables typed as dynamic still have a static type: the dynamic type. There is no way to change the type of a *variable*.
Eric Lippert
+1  A: 

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?

Hun1Ahpu
Polymorphism, of course.
Ignacio Vazquez-Abrams
+1  A: 

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

Michael Buen
Unless you are dealing with a value type no box is created so the term "unbox" is inappropriate. Value types are put into a box if used as object so they can be put on the heap (normally value objects can only live on the stack).
helium
damn, you're so pedantic. what term should i use then?
Michael Buen
+1 because this answer of all so far seems to come closest to what the OP asked for. However, you might initially have to set `mydb` to `null` in order to avoid a compiler warning/error.
stakx
A: 

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.

helium