Ice::Object and checked cast

Understand how to provide interoperable services with IceRPC + Slice.

With Ice, all Slice interfaces implicitly derive from the Ice::Object interface, which provides four operations: ice_id, ice_ids, ice_ping and ice_isA.

The generated code implements these operations automatically. As an application developer using Ice, you typically don't think about these built-in operations.

With IceRPC, a Slice interface does not have any implicit base interface, and Ice::Object is just a regular interface:

slice
mode = Slice1
[cs::namespace("IceRpc.Slice.Ice")]
module Ice
/// Provides 3 ice_ operations. Services implemented with Ice or that offer compatibility with Ice implement this
/// interface.
[cs::identifier("IceObject")]
interface Object {
/// Gets the Slice type IDs of all the interfaces implemented by the target service.
/// @returns: The Slice type IDs of all these interfaces, sorted alphabetically.
idempotent ice_ids() -> Sequence<string>
/// Tests whether the target service implements the specified interface.
/// @param id: The Slice type ID of the interface to test against.
/// @returns: True when the target service implements this interface; otherwise, false.
idempotent ice_isA(id: string) -> bool
/// Pings the service.
idempotent ice_ping()
}

IceRPC does not provide the fourth operation, ice_id. With IceRPC + Slice, a service can implement multiple Slice interfaces and does not always have a single most-derived Slice interface / type ID.

When you implement a service with IceRPC + Slice, you decide if you want to implement this interface.

In C#, you implement Ice::Object like any other interface, except you don't need to actually implement any of the mapped interface methods. The IceRPC + Slice integration provides a default implementation for all these methods. For example:

C#
using IceRpc.Features;
using IceRpc.Slice; // for SliceService
using IceRpc.Slice.Ice; // for IIceObjectService (Slice Ice::Object)
[SliceService]
internal partial class HelloService : IHelloService, IIceObjectService
{
// IIceObjectService provides default implementations for all the ice_ operations.
public ValueTask SayHelloAsync(IFeatureCollection features, CancellationToken cancellationToken)
{
...
}
}

With Ice, you can call built-in Ice::Object operations using any proxy, but it is unusual to do so. There is however one hidden exception: ice_isA.

The Ice client demos, including the most basic Minimal demo, all start with a call to checkedCast.

checkedCast is a helper method that calls the ice_isA operation on the proxy being "checked cast": it asks the target service (Ice object with Ice's terminology) if it implements a specific Slice interface. While this check is unnecessary (uncheckedCast works just as well), it's shown by all Ice demos and is therefore very common.

The net result is: if you reimplement an existing Ice server with IceRPC, your services need to implement Ice::Object when they are being "checked cast" by existing Ice client applications.

If you like checkedCast and want to keep check-casting your proxies, the IceRPC + Slice integration provides an equivalent API: AsAsync. The target service must implement Ice::Object; otherwise, AsAsync will fail with a DispatchException with status code NotImplemented.

There is no need for an uncheckedCast API in IceRPC + Slice, because you can construct a proxy directly with its constructor. For example:

Ice client in C#
using var communicator = Ice.Util.initialize(ref args);
ObjectPrx proxy = communicator.stringToProxy(
"hello:default -h localhost -p 10000");
HelloPrx helloProxy =
HelloPrxHelper.uncheckedCast(proxy);
helloProxy.sayHello();
IceRPC + Slice client in C#
await using var connection = new ClientConnection(
new Uri("ice://localhost:10000"));
var helloProxy = new HelloProxy(
connection,
new Uri("ice:/hello"));
await helloProxy.SayHelloAsync();

Was this page helpful?

CookiesYour privacy
This website uses cookies to analyze traffic and improve your experience.
By clicking "Accept," you consent to the use of these cookies. You can learn more about our cookies policy in our Privacy Policy.