Writing an extension method for type T; How can I add a type constraint for the T field?

Initial situation:

I am working with a proprietary framework ( ESRI ArcGIS Engine ), which I want to extend with some new features. I decided to use extension methods in C # for this.

The following are parts of the infrastructure API that are relevant to this issue:

    +------------------------+                   IGeometry
    |  IFeature <interface>  |                   <interface>
    +------------------------+                       ^
    |  +Shape: IGeometry     |                       |
    +------------------------+             +---------+---------+
                                           |                   |
                                        IPoint              IPolygon
                                        <interface>         <interface>

What I want to do:

I want to write an extension method for IFeaturethat will allow the following:

IFeature featureWithPointShape   = ...,
         featureWithPolygonShape = ...;

// this should work:
featureWithPointShape.DoSomethingWithPointFeature();

// this would ideally raise a compile-time error:
featureWithPolygonShape.DoSomethingWithPointFeature();

, , (IPoint IPolygon) (IFeature), . IFeature, IFeature IGeometry, .


:

IFeature Shape (. ), ?

public static void DoSomethingWithPointFeature(this IFeature feature)
{
    if (!(feature.Shape is IPoint))
    {
        throw new NotSupportedException("Method accepts only point features!");
    }
    ...  // (do something useful here)
}

( - - IFeature, FeatureWithShape<IPoint>, -, - IFeature -?)

+3
5

, IFeature, Shape , IGeometry. IFeature, , IFeature framework, IFeature, Shape. , , , .

.NET 4.0, . , Shape.

+1

IFeature:

IFeature<IPoint>
IFeature<IPolygon>

constaint IFeature.

+1

, IFeature ArcObjects.

, . .

+1

, , , IFeature. IFeature (, ). , IFeature. : -)

IFeature, , . , .

+1

, , () ArcObjects .

, : . . .

Sebastian P.R. Gingter , IFeatureOf<T>, IFeature. , , .

, , IFeatureOf<IPoint> , , .

, , var notReallyAPointFeature = (IFeatureOf<IPoint>)myPolygonFeature;, IFeatureOF<>, , , .

:

using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;

class Program
{
    public interface IFeatureOf<T> : IFeature { };

    public static void AcceptsAllFeatures(IFeature feature) {
        //do something, not caring about geometry type...
        return;
    }

    public static void AcceptsOnlyPointFeatures(IFeatureOf<IPoint> pointFeature) {
        IPoint pointGeometry = (IPoint)pointFeature.Shape; //constraint guarantees this is OK
        //do something with pointGeometry
        return;
    }

    static void Main(string[] args)
    {
        IFeature pointFeature = new FeatureClass(); //this is where you would read in a feature from your data set
        IFeature polylineFeature = new FeatureClass();
        var constainedPointFeature = (IFeatureOf<IPoint>)pointFeature;
        var constrainedPolylineFeature = (IFeatureOf<IPolyline>)polylineFeature;

        AcceptsAllFeatures(constainedPointFeature);             //OK
        AcceptsAllFeatures(constrainedPolylineFeature);         //OK
        AcceptsAllFeatures(pointFeature);                       //OK
        AcceptsAllFeatures(polylineFeature);                    //OK

        AcceptsOnlyPointFeatures(constainedPointFeature);       //OK

        AcceptsOnlyPointFeatures(constrainedPolylineFeature);   //Compile-time error: IFeatureOf<IPolyline> != IFeatureOf<IPoint>
        AcceptsOnlyPointFeatures(pointFeature);                 //Compile-time error: IFeature != IFeatureOf<something>
        AcceptsOnlyPointFeatures(polylineFeature);              //Compile-time error: IFeature != IFeatureOf<something>
    }
}
0

Source: https://habr.com/ru/post/1752963/


All Articles