|
They all implement IComparable , don't they? Just use the where T:IComparable constrain in your generic method. Or perhaps use IComparable<T> .
[ My Blog] "Visual studio desperately needs some performance improvements. It is sometimes almost as slow as eclipse." - Rüdiger Klaehn "Real men use mspaint for writing code and notepad for designing graphics." - Anna-Jayne Metcalfe
|
|
|
|
|
Why do you use generics at all?
Wouldn't it just be simpler to do something like that:
public bool GetOperatorResult(string operator, bool a, bool b)
{
}
public bool GetOperatorResult(string operator, int a, int b)
{
}
and let the runtime decide which overload should be called?
-^-^-^-^-^-
no risk no funk ................... please vote ------>
|
|
|
|
|
I did think about this but I would have to create a function that does the same thing for every different type of number (int, double, long, etc....). Is there a way to get around this?
Also, I want to be able to pass in operands of type Object.
Thanks in advance.
-- modified at 11:42 Tuesday 4th September, 2007
|
|
|
|
|
How about if I created a function which takes operands of type Object and then calls other overloaded functions:
public bool getOperatorResult(string operatorType, System.Object operandA, System.Object operandB)
{
if (operandA is bool)
{
return getOperatorResult(operatorType, (bool)operandA, (bool)operandB);
}
else if (operandA is double)
{
return getOperatorResult(operatorType, (double)operandA, (double)operandB);
}
else if (operandA is int)
{
return getOperatorResult(operatorType, (int)operandA, (int)operandB);
}
else if (operandA is long)
{
return getOperatorResult(operatorType, (long)operandA, (long)operandB);
}
else if (operandA is string)
{
return getOperatorResult(operatorType, (string)operandA, (string)operandB);
}
else
{
return false;
}
}
public bool getOperatorResult(string operatorType, bool operandA, bool operandB)
{
switch (operatorType)
{
case "or":
return (operandA || operandB);
case "and":
return (operandA && operandB);
case "equal":
return (operandA == operandB);
case "notequal":
return (operandA != operandB);
default:
return false;
}
}
|
|
|
|
|
This is, at a minimum, not performant, as all your types are not objects, and would have to be boxed and unboxed.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
for boolean operators such as ^, &, |, &&, and ||, just use a simple switch. Then, if either the type of object is not bool OR if the operator is not one of the preceding, then see if the object implements icomparable. If so (which int and double both do), then return one of the following (you could even check first to see if the comparison is EQUAL or NOTEQUAL, then use .Equals which all objects expose)
public bool compare(object A, object B, comparison comp) {
IComparable ic = A as IComparable;
object other = B;
if (ic == null) {
ic = B as IComparable;
other = A;
comp = SwitchComparison(comp); // simple function that changes
// <= to >=, < to >, and vice versa
}
// check if ic is null... if so, do whatever you think is appropriate
switch (comp) {
case EQUALS:
return ic.CompareTo(other) == 0;
case NOTEQUALS:
return ic.CompareTo(other) != 0;
case GT:
return ic.CompareTo(other) > 0;
...
}
|
|
|
|
|
Anyone know how to deserialize a file, but not load the whole thing in to memory?
Sort of like using a Hashtable, jumping to a point within the file, modifying the data and then closing. Rather than, opening the whole thing up, then rewriting the whole file over and over again.
Thanks
Jeremy )
-- modified at 11:45 Tuesday 4th September, 2007
I think I may have found what I been looking for, it appears Memorystream might be what im looking for, anyone have any experience with this?
|
|
|
|
|
jblouir wrote: jumping to a point within the file, modifying the data and then closing. Rather than, opening the whole thing up, then rewriting the whole file over and over again.
Your talking about something like ISAM which is completely different than serialization.
|
|
|
|
|
Awesome, thanks for that. Looking in to it now. )
|
|
|
|
|
Hi,
I have a DLL written in C.
I would like to import it in C#(Visual Studio 2005).
How can I do that?
Thanks in advance,
|
|
|
|
|
|
you can't. You have to write p/invoke signatures that allow you to call methods on the dll, but you can't import it the way you can a COM or managed dll file.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
thanks,
can you explain please how to write p/invoke signatures .
|
|
|
|
|
You use dllimport, as the other poster said, and then you write a signature that matches the method. www.pinvoke.net[^] has lots of examples, it's probably a great place to start.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Hello,
I am currently working on an app that needs the ability to inquire about capabilities of scanners.
I am using the definitions of this project. The problem that appears here is the use of unmanaged library twain_32.dll. All methods imported with dllimport work fine except the DSCap(...) method returns failure code when inquiring about capabilities.
The method DSCap should set the TwCapability variable that is passed with. This TwCapability is defined in the original header file of the twain_32.dll as follows:
typedef struct {
TW_UINT16 Cap;
TW_UINT16 ConType;
TW_HANDLE hContainer;
} TW_CAPABILITY, FAR * pTW_CAPABILITY;
where TW_UINT16 is defined as "typedef short TW_INT16, FAR *pTW_INT16; "
and TW_HANDLE is defined as "typedef HANDLE TW_HANDLE; "
"ConType" gives information about the type of the container that holds the capabilities information and "hContainer" is the pointer to the real capabilities information data.
This TW_CAPABILITY struct is defined in the c# code as follows:
[StructLayout(LayoutKind.Sequential, Pack = 2)]
internal class TwCapability
{
public TwCapability(TwCap cap)
{
Cap = (short)cap;
ConType = -1;
}
~TwCapability()
{
if (hContainer != IntPtr.Zero)
Twain.GlobalFree(hContainer);
}
public short Cap;
public short ConType;
public IntPtr hContainer;
}
To make things easier for you this is the "step by step guide" of how to inquire scanner capabilities from the official TWAINSpec.pdf taken from www.twain.org:
Step 1:
Application allocates a TW_CAPABILITY structure and fills its fields as follows:
• Cap = the CAP_ or ICAP_ name for the capability it is interested in
• ConType = TWON_DONTCARE16
• hContainer = NULL
Step 2:
Application uses the TW_CAPABILITY structure in a DG_CONTROL /
DAT_CAPABILITY / MSG_GET operation.
Step 3:
The Source examines the Cap field to see if it supports the capability. If it does, it creates
information for the application. In either case, it sets its Return Code appropriately.
Step 4:
Application examines the Return Code, and maybe the Condition Code, from the
operation.
If TWRC_SUCCESS then the Source does support the capability and
• The ConType field was filled by the Source with a container identifier
(TWON_ARRAY, TWON_ENUMERATION, TWON_ONEVALUE, or
TWON_RANGE)
• The Source allocated a container structure of ConType and referenced the
hContainer field to this structure. It then filled the container with values
describing the capability’s Current Value, Default Value, and Available Values.
Based on the type of container and its contents (whose type is indicated by it ItemType
field), the application can read the values. The application must deallocate the
container.
If TWRC_FAILURE and TWCC_CAPUNSUPPORTED
• Source does not support this capability
This is how I try inquiring about the caps:
public void GetCapabilities()
{
TwRC rc;
TwCapability twCap = new TwCapability(TwCap.XferCount);
rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Get, twCap);
if (rc == TwRC.Success)
{
MessageBox.Show("worked!");
}
else MessageBox.Show("not!");
}
I always get TWRC_FAILURE in return, though XFERCOUNT must be supported by every scanner.
I suspect the hContainer variable to be the problem, but I am new to c# and interops.
This is the dllimport of the method:
[DllImport("twain_32.dll", EntryPoint = "#1")]
private static extern TwRC DScap([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwCapability capa);
I know this is a lot of information, but I hope someone has already worked with TWAIN under .net and can help me fix this problem.
Thx in advance
Dominik
|
|
|
|
|
Hi,
I have a backgroundworker that executes a method that returns a string[].
In turn, that string[] is returned via e.Result.
How do I convert the object e.Result into a string[]?
eg
string[] = fileList;
...
do backgroundwork
...
fileList = e.Result;
Thanks,
Glen Harvy
|
|
|
|
|
fileList = (string[])e.Result;
|
|
|
|
|
|
Which one will be a good practice
using ( class1 c1 = new class1() )
{
}
or
class1 c1 = new class1()
try
{
}
finally
{
c1.Dispose();
}
If first one is good what will happen to the object if any error happened in between the process ? Will it be disposed ?
|
|
|
|
|
using is always good practice. I'd put my try/catch inside the using block, if I felt an exception was likely to occur. I would never write a try block by default. If I don't foresee a possible exception, I want it to throw, so I find out about it.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Christian Graus wrote: using is always good practice.
Thanks,
Assume I am not calling the dispose method and not using the using keyword. Then how long unmanaged object would be in memory ? Or will it automatically disposed when scope ends ?
|
|
|
|
|
N a v a n e e t h wrote: Then how long unmanaged object would be in memory ?
If you create an object which contains an unmanaged object, it will remain active until garbage collection picks the object up. You should not risk this, regardless of the fact that anythign in a using block probably lives for such a short time that it should, in theory, be collected pretty quickly.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
Christian Graus wrote: f you create an object which contains an unmanaged object, it will remain active until garbage collection picks the object up
The garbage collector will not pick up an unmanaged object. That's why it is called unmanaged.
Or am I missing something?? Must be the case then Christian is always right, isn't he?
-^-^-^-^-^-
no risk no funk ................... please vote ------>
|
|
|
|
|
I am assuming that the 'unmanaged object' is something that is being held in a managed object, for example, a HDC in a graphics object. In this instance, when the graphics object is finalised, it should release the HDC. I was wording my reply carefully, I wasn't sure if he realised that an IDisposable is, by definition, a managed object. Of course, if you create an HDC directly via p/invoke, no GC will ever occur, nor is the object going to impliment IDisposable, making the whole discussion moot.
Christian Graus - Microsoft MVP - C++
"I am working on a project that will convert a FORTRAN code to corresponding C++ code.I am not aware of FORTRAN syntax" ( spotted in the C++/CLI forum )
|
|
|
|
|
They both to the same (well using first checks if c1 isn't null) but the first one is easier to understand and use
|
|
|
|
|