C#: Declaration in if Statement
In C++ I like to code as follows:
class Base {};
class Derived : Base {};
Base* b = ReturnsBaseOrDerived();
if (Derived* d = dynamic_cast<Derived*>(b))
{
DoSomething(d);
}
Here d is declared, initialized, and tested against NULL in one line. Moreover it is only visible in the body of the if statement, where it is guaranteed not to be NULL.In C#, this is not allowed. We could instead write this:
Derived d = b as Derived;
if (d != null)
{
DoSomething(d);
}
DoSomethingElse(d); // here d is still visible, but may be null
This
if (b is Derived)
{
DoSomething(b as Derived);
}
results in b being cast to Derived twice. FxCop will emit a warning. We cannot declare a variable in an if statement, but we can do it in a foreach statement:
foreach (Derived d in Dynamic.CastHere Dynamic.Cast creates a collection containing 0 or 1 elements. To make this work, we define a helper class:(b)) { DoSomething(d); }
static public class Dynamic
{
public static Coll<T> Cast<T>( object obj) where T: class
{
return new Coll<T>( obj);
}
public class Coll<T> : IEnumerable<T> where T : class
{
object m_object;
public Coll( object obj) { m_object = obj; }
public IEnumerator<T> GetEnumerator()
{
T t = m_object as T;
if (t != null)
yield return t;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
T t = m_object as T;
if (t != null)
yield return t;
}
}
}
OK, I would not really propose using this code, but at least it demonstrates that workarounds for some of the deficiencies in C# can be found.
Propertypages zur Laufzeit spezifizieren
Erstellt man mit MFC ein ActiveX-Control, so wird mit den Macros BEGIN_PROPPAGEIDS etc. festgelegt, welche PropertyPages ISpecifyPropertyPages auflistet. Wenn man das Verhalten zur Laufzeit ändern möchte, helfen die folgenden erweiterten Makros:
// Modified versions of the MFC macros allowing to determine at run time
// which property pages to specify.
#define BEGIN_PROPPAGEIDS_EX(class_name, count)\
static CLSID _rgPropPageIDs_##class_name[count];\
AFX_COMDAT ULONG _cPropPages_##class_name = (ULONG)-1;\
LPCLSID class_name::GetPropPageIDs(ULONG& cPropPages) {\
LPCLSID pIDs = _rgPropPageIDs_##class_name;\
ULONG iPageMax = count;\
ULONG iPage = 0;
#define PROPPAGEID_EX(clsid, show)\
ASSERT(iPage < iPageMax);\
if (show)\
pIDs[iPage++] = clsid;
#define END_PROPPAGEIDS_EX(class_name)\
_cPropPages_##class_name = iPage;\
cPropPages = _cPropPages_##class_name;\
return _rgPropPageIDs_##class_name; }
// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS_EX(CMyCtrl, 2)
PROPPAGEID_EX(CPropPage1::guid, ShowPropPage1())
PROPPAGEID_EX(CPropPage2::guid, ShowPropPage2())
END_PROPPAGEIDS_EX(CMyCtrl)
Catastrophic Failure (HRESULT = 8000FFFF)
Sie haben mit MFC eine Komponente erstellt und erhalten die o.g. Fehlermeldung, wenn Sie eine Methode aufrufen? In diese Falle bin ich auch getappt. Die Lösung hat MS hier versteckt: HOWTO: Use an OLE Control as an Automation Server. Kurz gesagt, man muss im Server IsInvokeAllowed( DISPID) überschreiben und TRUE zurückgeben.[Home]

