Литой словарь в словарь - PullRequest
       8

Литой словарь в словарь

2 голосов
/ 09 апреля 2020

У меня есть эти 2 объекта, словарь и метод

public abstract  class Thing {}
public class Star : Thing {}

Dictionary<int, Star> dictStar;

public void listBoxAdd (Listbox listBox, Dictionary<int, Thing> thingDict){}

Я хочу вызвать метод с помощью dictStar. Я попробовал кучу вещей, чтобы составить свой словарь, и ничего, что я пытался, сработало. Я думаю, что это должно работать, но компилятор не согласен.

listBoxAdd (starList, ( Dictionary<int, Thing>) dictStar);

Я получаю ошибку CS0030, что c# не может преобразовать словарь звезд в словарь вещей.

Есть несколько других классов, основанных на вещах, и мой дизайн требует, чтобы словари их передавались методам, которые будут работать с полями в Thing. Есть несколько раз, когда у меня есть методы, которым нужен только материал, определенный в Thing.

У меня нет проблем с приведением Звезды к Вещи, но у меня проблема со словарем. Я попытался заставить метод взять словарь int, object, и я мог бы вызвать его, но в методе я не смог преобразовать словарь объектов в Tings.

Если я использую звездные словари в методе и вызываю его, он работает хорошо.

Я даже использую базовый класс Thing со Star, производным от него.

Я пришел из старых времен мейнфреймов 64K и постоянно думаю об использовании памяти и машинных циклах, поэтому в В дополнение к тому, чтобы быть не элегантным, просмотр словаря и вызов каждого элемента, хотя он будет работать, кажется плохой идеей.

Я знаю, что многие правила используются для того, чтобы c# мог очистить неиспользуемые вещи в памяти, но нет опасности, что элементы исчезнут во время вызова.

1 Ответ

2 голосов
/ 10 апреля 2020

Я объясню, почему это запрещено C#. Давайте определим второй подкласс public class BlackHole : Thing {}

Теперь, если вы можете преобразовать словарь звезд в словарь вещей, как вы пытаетесь var dicThings = (Dictionary<int, Thing>) dictStar

Вы могли бы написать позже dicThings.Add(5, new BlackHole());, но там проблема с этим: тип runtime dicThings по-прежнему будет словарём звезд ... с черной дырой.


Решение:

Вы может превратить ваш метод в обобщенный c с ограничением на тип, например listBoxAdd<T> .... where T : Thing


Вот полный пример кода:

using System;
using System.Collections.Generic;

public class Program
{
    public abstract  class Thing {}
    public class Star : Thing {}
    public class BlackHole : Thing {}

    public static void DoThing (Dictionary<int, Thing> thingDict) { Console.WriteLine("DoThing"); }

    public static void DoThingMagic<T> (Dictionary<int, T> thingDict) where T : Thing { Console.WriteLine("DoThingMagic"); }

    public static void Main()
    {
        Dictionary<int, Star> dictStars = new Dictionary<int, Star>();

        // line below has a compilation error to protect you from mixing stars with black holes ;)
        Dictionary<int, Thing> dictThings = (Dictionary<int, Thing>) dictStars;
        // it explains the method call has a compilation error too:
        DoThing(dictStars);

        // now this method call will compile and execute:
        DoThingMagic(dictStars);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...