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.Cast(b))
{
	DoSomething(d);
}
Here Dynamic.Cast creates a collection containing 0 or 1 elements. To make this work, we define a helper class:
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]
free counters

powered by suchticker.de - der Seo Suchmaschine