|
Actually, its perfectly valid. The Application.DoEvents keeps the message pump pumping and is the way mutitasking used to work in the Windows 3.x world.
Admittedly, I prefer your way of doing it but the gentleman suggested he didn't want to use background threads.
Regards,
Rob Philpott.
|
|
|
|
|
I've never used the Application.DoEvents() function. Didn't even know the existance of it.
With that in my mind, I totaly agree with you.
|
|
|
|
|
I tried using this code for reading excel data using c# :
bt the following part of the code is giving errors and is not being executed....
plz help !!!!
using System;
using System.Collections.Generic;
using System.Text;
using Excel;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string Path = @"c:\gg.xls";
Excel.ApplicationClass app = new ApplicationClass();
Excel.Workbook workBook =
app.Workbooks.Open(Path,0,true,5,"","",true,Excel.XlPlatform.xlWindows,"\t",false,false,0,true,1,0);
Excel.Worksheet workSheet = (Excel.Worksheet)workBook.ActiveSheet;
int index = 0;
object rowIndex = 2;
object colIndex1 = 1;
object colIndex2 = 2;
try
{
while (((Excel.Range)workSheet.Cells[rowIndex, colIndex1]).Value2 != null)
{
rowIndex = 2 + index;
string firstName = ((Excel.Range)workSheet.Cells[rowIndex, colIndex1]).Value2.ToString();
string lastName = ((Excel.Range)workSheet.Cells[rowIndex, colIndex2]).Value2.ToString();
Console.WriteLine("Name : {0},{1} ", firstName, lastName);
index++;
}
}
catch (Exception ex)
{
app.Quit();
Console.WriteLine(ex.Message);
}
}
}
}
the error is at "Excel.Workbook workBook = app.Workbooks.Open" :
Error 1
No overload for method 'Open' takes '15' arguments C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Projects\ConsoleApplication1_trytry\ConsoleApplication1_trytry\Program.cs 16 39 ConsoleApplication1_trytry
|
|
|
|
|
Well, that's saying you've got the wrong number of arguments in the open method. Check the documentation on 'Open'.
Regards,
Rob Philpott.
|
|
|
|
|
Hi All,
Please let me know if we can cast a known type to a generic type...
private static T InitData<T>(T dummyColl, int value)
{
List<SampleData> SampleColl = new List<SampleData> {
new SampleData {
Age = 23,
Name="abc"
}
};
dummyColl = (T)SampleColl;
}
Is there any other way around to get this??
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
It would probably throw an exception if you don't use a Collection type, but try (T)Convert.ChangeType(SampleColl, typeof(T)) . Bear in mind that this will convert the list itself. If you want to convert the objects inside the list, then use SampleColl.Cast<t>()</t>
|
|
|
|
|
It is not very clear from your sample what you are trying to do.
If you are doing this to cast a collection (hence the dummyColl name?), you would probably want to do something like:
private static List<t> CastToDerivedType<t>(List<basetype> list) where T : BaseType
{
List<t> result = new List<t>();
foreach (BaseType item in list)
result.Add(item as T);
return result;
}
</t></t></basetype></t></t>
Try explaining what is your goal first.
|
|
|
|
|
|
Just a note - you should note that this line:
dummyColl = (T)SampleColl;
doesn't do anything to the actual dummyColl being passed to the method.
So this kind of casting at the end of your method doesn't do anything.
|
|
|
|
|
I agree...Actually while working for the solution I've passed the dummyColl argument to the method that's because I thought I can get the T type by using dummyColl.GetType().(But I forgot that, to get Type there is actually 'typeof' exists in .NET )
Also using
veki-peki wrote: dummyColl = (T)SampleColl;
gives me a compiler error!!! Cannot convert List type to T
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
As it stands it won't work as T could be anything and so casting from SampleColl to T may very well not work.
Try this, use 'as':
dummyColl = SampleColl as T;
you'll need (I think) to add a constraint to your generic method
private static T InitData<T>(T dummyColl, int value) where T: class
.. because T might be a value type and you need to constrain it to reference types to use as.
If you're not familiar with constraining generic types and methods have a read up on that - that should help you quite a bit but it's hard to offer advice without knowing what derives from what.
Regards,
Rob Philpott.
|
|
|
|
|
Rob Philpott wrote: T could be anything and so casting from SampleColl to T may very well not work
I agree with you...but at the calling site itself I have confined T for only two data types (as per the requirement). So in my code there is never a chance that T is a value type
Rob Philpott wrote: private static T InitData<t>(T dummyColl, int value) where T: class
I've used this but frankly I don't understand its usage...even with that 'where' clause I'm able to do something like this without any compiler error.
int i=2;
(T)Convert.ChangeType(i, dummyColl.GetType())
So whether I use this constraint or not it throws the error at runtime only.Can you please let me know why is it happening?
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
Spunky Coder wrote: but at the calling site itself I have confined T for only two data types
That's unimportant. The compiler needs to compile your function, and in order to do that it needs to know a bit about T. If it knows nothing about T, it has to assume it could be anything and therefore won't accept your cast. By constraining the function, your telling the compiler something about T, enough for it to be satisfied that the cast will always work. Don't forget your assembly might be used in other projects written by other people- how can you guarantee that they'll call it the correct way?
Spunky Coder wrote: So whether I use this constraint or not it throws the error at runtime only.Can you please let me know why is it happening?
What's the error?
Regards,
Rob Philpott.
|
|
|
|
|
Well, the error is a runtime error. "Cannot convert System.Int32 to List". Here List is the type of T passed to this method.
Even when I don't use the 'where' class, the same runtime error is shown when executing the line
int i=2;
(T)Convert.ChangeType(i, dummyColl.GetType())
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
Well, I'm not sure what the question is here. Of course, you cannot cast an int to a list. They're completely different things.
Steer clear of Convert.ChangeType. You won't get any compile time checking with this and compiler errors are always more favourable than runtime ones.
Regards,
Rob Philpott.
|
|
|
|
|
Hmmm...I was asking for the use of 'where T:class '. Anyhow I got it from google about the Constraints on Type Parameters.
Thanks for the information.
"Don't worry if it doesn't work right. If everything did, you'd be out of a job." (Mosher's Law of Software Engineering)
|
|
|
|
|
But you still didn't say why you are trying to do this? Casting Int32 to a List<> doesn't make much sense, so it is natural that you will get this error.
There may be a better solution to your problem, so try to explain what is the actual problem that got you thinking about casting with generic parameters?
|
|
|
|
|
Hi all,
I'm wondering why C# imposes restrictions on assignments using output parameters that are not otherwise present. Presumably there is some logical reason for it, but I can't think of it.
Assume this code:
public interface SomeInterface { }
class A : SomeInterface
{
public SomeInterface Field;
void foo()
{
Parse(out this.Field);
}
static public void Parse(out A something)
{
something = new A();
}
}
This code will not build - instead, the compiler will inform you that The best overloaded method match for A.Parse(out A)' has some invalid arguments . Since A implements SomeInterface, Field is of course assignable to A, but nevertheless it does not build. If I instead write the code so that Parse returns A and the assignment is done in foo(), it builds without as much as a warning, as it should.
void foo()
{
Field = Parse();
}
static public A Parse()
{
return new A();
}
This causes some minor annoyances for me as I'm using the compiler-compiler Coco/R to generate a parser for a language of my creation. This tool lets me specify the parser by means of what's called an attributed grammar, and the generated code uses the attributes in the grammar and maps them to parameters. What I wanted to do was to use an output parameter for most productions in the grammar, like this:
Term<out term="" t=""> = (. t = new Term(); Factor f; .)
Factor<out f=""> (. t.Mul(f); .)
{
'*' Factor<out f=""> (. t.Mul(f); .)
| '/' Factor<out f=""> (. t.Div(f); .)
}
.
This straightforwardly leads to a generated method for parsing a Term that looks like this:
void Term(out Term t)
{
t = new Term(); Factor f;
Factor(out f);
t.Mul(f);
while (la.kind == 15 || la.kind == 16)
{
if (la.kind == 15)
{
Get();
Factor(out f);
t.Mul(f);
}
else
{
Get();
Factor(out f);
t.Div(f);
}
}
}
My little problem arises because I've modeled Factor as an interface type. I want to be able to later on write a new class that performs some calculation or other, be free to derive this class from any class I wish, and so I've defined a simple interface IScalar { decimal GetValue(); } so that any class implementing it can be used as a factor.
I've modeled arithmetic expressions as a list of terms with + or - between them, a Term as shown above as a list of factors separated by * or /, and a Factor as a number, built-in function of the language, variable, or '(' Expr ')' - this model is sufficient to get correct operator precedence and handle nested expressions correctly.
It's not much of an issue as I can declare the output parameter to be of the interface type (these methods are private and only used internally in the parser after all), but I do wonder why C# imposes this restriction on output parameters. Or even if it really does - I haven't checked the language specification and it could be that it's the compiler rather than the spec that restricts me, though it seems a stretch.
|
|
|
|
|
I've been staring at your bit of code for about ten minutes now. I feel like I should know the answer to this but I'm not sure I do. Essentially I guess it's that .NET can't do upcasting when using Out parameters and an exact type match is required.
Can't you do something with the compiler-compiler not to use this construct. I rather dislike out parameters and try to avoid them? Either that or use a local variable of the correct type then assign the interface type to that?
Regards,
Rob Philpott.
|
|
|
|
|
I can't do anything not to use this construct if I want the method parsing a production to instantiate the object - there's no way to specify that I want to use a return type instead of an output parameter. I can use normal in parameters and also ref, but it doesn't solve the problem.
I can use a local variable in the parsing method, but then it kind of nullifies the point of using polymorphism - I didn't want to have to write any code for each specific type. It's not really a lot in this case, but I think I'd prefer to just make a method that parses a number "return" (i.e. use an output parameter of type) IScalar rather than Number.
The exact same issue exists if I use inheritance instead of interfaces to achieve polymorphism. That is, if a field is of type BaseClass and a method has an output parameter of type DerivedClass, I cannot assign the field using an out parameter. So I need to put the knowledge of what specific type it is in every context it is used.
A possible solution would be to omit the parameters completely and make a stateful parser. I could put expressions onto a stack as I parse them (Coco supports "semantic actions", which is any C# code I wish to insert when something is parsed, so I can call custom methods in my parser - this is usally used for things like looking up in symbol tables or even emitting opcodes). Then, when I parse a number, it would find the Factor on the stack and assign the scalar to it. But it's a pity to have to create a stack that basically just recreates the structure that is already present on the call stack! That, after all, is the basic idea behind a recursive-descent parser!
I'm asking more out of curiosity (I try to see stuff I don't understand as an opportunity to learn something new) than anything else. The minor friction it creates in the parser code is overcome by pragmatically changing so I use the interface type everywhere, e.g. <code>Number(out IScalar s)</code> instead of <code>Number(out Number n)</code> and I'm good to go. I don't really see any problems with this. If I want to make something like a syntax highlighter later on this logic would anyway have to examine the run-time type of the Scalar field, since this has to accept any type of scalar.
Thanks anyway!
|
|
|
|
|
dojohansen wrote: Since A implements SomeInterface, Field is of course assignable to A, but nevertheless it does not build.
Assuming the compiler allowed that, guess what would happen if someone wrote
interface ISome {}
class SomeA : ISome {}
class SomeB : ISome {}
void Method()
{
SomeA a = new SomeA();
OutMethod(out a);
}
void OutMethod(out ISome some)
{
some = new SomeB();
}
Boom, a variable typed to be SomeA is now referring to an object of type SomeB , something that is not legal.
|
|
|
|
|
For some reason I never got a notification of this reply and I only read it now after tumbling around the "my codeproject" pages.
Therefore the great delay in saying Thank you, Sir - it makes perfect sense now! In fact, I should have thought of it. But I did not.
|
|
|
|
|
I spoke too soon.
Unfortunately your example doesn't explain anything. The assignment your code example does is unsafe (based on the declared types), and it would not compile if you did the same assignment using return values instead of output parameters.
I should have spotted this immediately, because that's another way of posing my original question: Why should output parameters have different assignability than return values?
Too see why your example misses the point, consider if we modified your code like this:
void Method()
{
SomeA a = Method2();
}
ISome Method2()
{
return new SomeB();
}
Here, and in your example with the out parameters, we're attempting to assign a field of type SomeA to a reference of type SomeB, which is unsafe. But in my original code the assignment I'm trying to do is known to be safe, as you can verify since the same assignment done from a return value rather than an out parameter builds just fine (and indeed runs fine).
Nor has it got anything to do with the fact that I pass a field rather than a local variable; the same issue arises if I use a local. The compiler complains it can't convert the concrete type to the interface type, but it plainly can and does so if I declare the out parameter as having the interface type...
It makes no sense to me, and I'm still hoping someone can shed light on this.
|
|
|
|
|
dojohansen wrote: and it would not compile if you did the same assignment using return values instead of output parameters.
It would compile if you cast the return value to SomeA
SomeA a = (SomeA) Method2();
dojohansen wrote: But in my original code the assignment I'm trying to do is known to be safe, as you can verify since the same assignment done from a return value rather than an out parameter builds just fine (and indeed runs fine).
I guess I used the wrong example - here's what you are trying to do
interface ISome {}
class SomeA : ISome {}
class SomeB : ISome {}
void Method()
{
ISome some = SomeB();
Method2(out some);
}
void Method2(out SomeA some)
{
some = new SomeA();
}
The problem here is ISome need not refer to SomeA, it could refer to any class that implements ISome, but Method2 is expecting SomeA. In fact, the code wouldn't compile even if you removed the out keyword.
The code would compile if you changed the parameter of Method2 to out ISome some instead.
Casting to SomeA when calling Method2 would also work, but not if the parameter is out . The variable you're passing as out needs to be assignable, and the cast expression is not assignable.
And about it working for return types, welcome to the world of covariance and contravariance[^]. Return values are covariant, method parameters are contravariant, which means that return values could be more derived than what the caller expects, whereas method parameters could only be equal or less derived than the caller's parameters.
|
|
|
|
|
I'm afraid you are still not getting my question. I'm fully aware that it doesn't compile if I use the specific type that the function actually assigns to the out parameter as the declared type of that parameter. But my point is that I see absolutely no reason why it should not.
Again, if you simply frame the issue as "why should (output/ref) parameters have different assignability compared to return values?" it should become clear that your reply does not answer the question.
One detail while I'm at it: When using the output parameter it makes little sense to initialize the variable; just declare it. But let's not go off topic on that one.
|
|
|
|
|