1

オブジェクトの1つが別のインターフェースのリストであるインターフェースを定義することは可能ですか?

2つのEFオブジェクトがあります。

=====

class ImageType1
{
    string Id
    string Name
    List<ImageType1Size> Sizes
}

class ImageType1Size
{
    string Id
    int Width
    int Height
}

class ImageType2
{
    string UserId
    string ImageId
    string Name
    List<ImageType2Size> Sizes
}

class ImageType2Size
{
    string UserId
    string ImageId
    int Width
    int Height
}

=====

画像サイズクラスごとに、すべてのプロパティがキーになります(補足説明のみ)。

ここで、私がやりたいのは、次の2つのインターフェースを作成することです。

=====

interface IImage
{
    string Name
    List<ImageSize> Sizes
}

interface IImageSize
{
    int Width
    int Height
}

=====

私のプロジェクトでは、それぞれのインターフェイスを使用して、ImageType1、ImageType1Size、ImageType2、およびImageType2Sizeのパーシャルを作成しました。

ImageType1とImageType2のSizesプロパティをキャストして、インターフェイスIImageSizeを使用しようとするとエラーが発生します。

=====

これは可能ですか?よくわからない場合はお知らせください。質問を言い換えます。

ありがとう!

4

6 に答える 6

2

ここでジェネリックを検討することをお勧めします。

interface IImage<TSize> where TSize : IImageSize
{
    List<TSize> Sizes { get; }
}

class ImageType1 : IImage<ImageType1Size>
{
    List<ImageType1Size> Sizes { get; private set; }
}

または、これは機能します。

interface IImage
{
    IEnumerable<IImageSize> Sizes { get; }
}

class ImageType1
{
    public List<ImageType1Size> SizeList { get; private set; }

    public IEnumerable<IImageSize> Sizes { get { return SizeList; } }
}

これは、データの操作方法に最適なものによって異なります。

于 2012-10-04T21:17:06.343 に答える
0

ImageType1クラスの署名により、ImageType1.SizesにはImageType1Sizeオブジェクトのみが含まれるようになり、ImageType1.Sizes内にIImageSizeを格納することはできません。これにより、ImageType1Size以外のオブジェクト(たとえば、ImageType2Size)をリストに追加できるようになります。

これは、古いIImageSizeをImageType1.Sizesに保存できないことを意味します。これは、おそらく必要なものです。

ただし、他の操作を行う場合は、ImageSize1オブジェクトとImageSize2オブジェクトをIImageSizesであるかのように使用できます。

void Test()
{
    ImageType2 image = new ImageType2();
...
    foreach(var size in image.Sizes)
    {
        if(IsTooBig(size))
        {
            MessageBox.Show("I'm too big!")l
        }
    }
}

bool IsTooBig(IImageSize imagesize)
{
    return imagesize.Width > 500;
}

これで、ImageType1SizeオブジェクトとImageType2Sizeオブジェクトの両方でIsTooBigを使用できます。

于 2012-10-04T21:09:58.467 に答える
0

これまで、リストをリストにキャストすることについての議論がありました。

ここでそれについて読むことができますが、その要点は、C#ではそれを行うことができないということです。

C#-タイプList<Product>をList<IProduct>に暗黙的に変換することはできません

于 2012-10-04T21:13:09.510 に答える
0

foreach (IImageSize iSize in list) { int iWid = iSize.Width; }

于 2012-10-04T21:16:56.013 に答える
0

default.kramerが言ったことに基づいてIImage、他の場所でタイプとして明示的に必要な場合は、次のようにインターフェイスを分割できます。

interface IImage
{
  string Name
}
interface IImage<TSize> : IImage where TSize : IImageSize
{
    List<TSize> Sizes { get; }
}

class ImageType1 : IImage<ImageType1Size>
{
    List<ImageType1Size> Sizes { get; private set; }
}

IImageこれを行わないと、を指定せずにベアを作成することはできませんTSize。もちろん、Sizes非ジェネリックのプロパティにアクセスできるようにする必要がある場合IImageは、次のような拡張メソッドを追加する必要があります。

static class IImageHelper
{
  static List<IImageSize> GetSizes<TSize>(this IImage<TSize> image) where TSize: IImageSize
  {
    return image.Sizes.OfType<IImageSize>();
  }
}
于 2012-10-04T21:26:59.900 に答える
0

残念ながら、これはできません。理由を説明するときは、インターフェイスの外部で問題を検討することが役立ちます。

public void Example()
{
  List<ImageType1Size> Sizes1 = new List<ImageType1Size>();
  List<ImageType2Size> Sizes2 = new List<ImageType2Size>();
  List<IImageSize> Sizes;

  Sizes1 = Sizes; // These won't compile because the compiler can't guarantee that an
  Sizes2 = Sizes; // IImageSize is an ImageType1Size. It could be an ImageType2Size

  Sizes = Sizes1; // These will compile because the compiler knows that both 
  Sizes = Sizes2; // ImageType1Size and ImageType2Size are IImageSize's
}

これで、これをクラスと比較できます。

class ImageType1 : IImageType
{
  string Id {get; set;}
  string Name {get; set;}
  List<ImageType1Size> Sizes {get; set;} // This is just like Sizes1 = Sizes in the
                                         // example above.
}

public void Test(IImageSize imageSize)
{
  IImageType imageType = new ImageType1();

  imageType.Add(imageSize) // This would compile, as IImageType.Sizes will 
                           // take any IImageSize

  // But what really happens behind the interface is this:
  ((ImageType1)imageType)Sizes.Add(imageSize);    

  // Trying to insert an IImageSize into the collection
  // doesn't work, because the compiler can't guarantee that 
  // it's an ImageType1Size
}

注:あなたの例が表示されていると仮定しています

interface IImage
{
  string Name
  List<ImageSize> Sizes
}

実際にあるはずです

interface IImage
{
  string Name
  List<IImageSize> Sizes
}

他の場所でタイプ「ImageSize」について言及していないので。

于 2012-10-04T21:30:25.703 に答える