2013-03-06 3 views
0

У меня есть класс «ImageElementCollection: ConfigurationElementCollection», содержащий элементы класса «ImageElement: ConfigurationElement».Почему эта коллекция содержит объекты?

Используя советы некоторых других очень умных людей здесь, на StackOverflow, я понял, как использовать эти пункты в моей программе:

MonitorConfig Config = (MonitorConfig)ConfigurationManager.GetSection("MonitorConfig"); 

Однако при попытке доступа к элементам в этом коллекция ...

foreach (var image in Config.Images) Debug.WriteLine(image.Name); 

... Я в конечном итоге с волнистых линий под свойством Name, потому что «образ» был объявлен как объект, а не как ImageElement, несмотря на все мои усилия.

Является ли это чем-то, что я делаю неправильно в своих объявлениях, или это просто то, что каждый просто имеет дело с заменой «var» на «ImageElement» в этом foreach там?

Код для обработчика конфигурации приведены ниже:

public class MonitorConfig : ConfigurationSection 
{ 
    [ConfigurationProperty("Frequency", DefaultValue = 5D, IsRequired = false)] 
    public double Frequency 
    { 
     get { return (double)this["Frequency"]; } 
    } 

    [ConfigurationProperty("Images", IsRequired = false)] 
    public ImageElementCollection Images 
    { 
     get { return (ImageElementCollection)this["Images"]; } 
    } 
} 

[ConfigurationCollection(typeof(ImageElement), AddItemName = "Image")] 
public class ImageElementCollection : ConfigurationElementCollection 
{ 
    public ImageElement this[object elementKey] 
    { 
     get { return (ImageElement)BaseGet(elementKey); } 
    } 

    public void Add(ImageElement element) 
    { 
     base.BaseAdd(element); 
    } 

    protected override ConfigurationElement CreateNewElement() 
    { 
     return new ImageElement(); 
    } 

    protected override object GetElementKey(ConfigurationElement element) 
    { 
     return ((ImageElement)element).Name; 
    } 
} 

public class ImageElement : ConfigurationElement 
{ 
    [ConfigurationProperty("Name", IsRequired = true, IsKey = true)] 
    public string Name 
    { 
     get { return (string)this["Name"]; } 
    } 
} 
+0

Попробуйте отключить 'var image' для' ImageElement image'. Он может быть неоднозначным и просто рассматривать его как объект типа. (отредактируйте: в вашем foreach, если я не был ясен ...) edit2: Я вижу, вы уже сделали это и, похоже, подразумеваете, что это работает. Тогда, я думаю, я хочу сказать «да, вот как я обхожусь». –

+0

Да, это прекрасно работает. Мне просто кажется странным что-то, что * определенно * типа X (например, когда вы наводите на него курсор, подсказка говорит «ImageElement») не вводится как таковая при объявлении с помощью «var». Может, это означало, что мой обработчик был сломан? – 2013-03-06 02:38:59

+3

ConfigurationElementCollection реализует ICollection и IEnumerable, которые предоставляют компилятору никакой подсказки относительно типа элементов, которые он содержит, поэтому по умолчанию используются элементы типа Object. Если в коллекции реализован общий интерфейс IEnumerable , компилятор сможет определить, что он должен использовать T вместо var. –

ответ

2

Эндрю Кеннан дал ответ на приведенные выше замечания: эта коллекция, кажется, содержит только объекты, потому что он не реализует IEnumerable <T>.

Кроме того, эту проблему можно устранить, слегка отрегулировав обработчик конфигурации. Просто добавьте IEnumerable интерфейс следующим образом ...

public class ImageElementCollection : ConfigurationElementCollection, IEnumerable<ImageElement> 

... А потом воткнуть метод несколько, как это в теле класса:

public new IEnumerator<ImageElement> GetEnumerator() 
{ 
    var iter = base.GetEnumerator(); 
    while (iter.MoveNext()) yield return (ImageElement)iter.Current; 
} 

Спасибо, Эндрю.

+0

(Кстати, если вы хотите, например ... ответ, я заберу ваш.: P) – 2013-03-06 03:10:20

Смежные вопросы