Хорошо, так что я думаю, что вы пытаетесь сделать это сопоставить все в:
<rules>
<autoStart></autoStart>
<noMore></noMore>
<unExpectedCrush></unExpectedCrush>
</rules>
к списку правил. И вы просто пытаетесь запустить десериализацию непосредственно в XML и предполагаете, что он волшебным образом отобразит потомков rules
в IRule
.
Если вы действительно хотите получить список правил, сначала вы должны каким-то образом извлечь информацию. Это проще всего сделать, отобразив XML в типизированный объект. Так что в вашем случае вместо того, чтобы заканчивать списком, я бы сделал объект отображения:
public class Rules
{
public string AutoStart { get; set; }
public string NoMore { get; set; }
public string UnExpectedCrush { get; set; }
}
Так что-то вроде:
(Rules) ruleSerializer.Deserialize(config.Rules.CreateReader());
Теперь у вас есть объект, в котором отображаются все ваши правила. И с этого момента вы можете переназначить свойства в список правил. Но я думаю, что фактический объект Rules, в котором названы правила, часто более понятен другим людям, которые могут прочитать ваш код. Это всего лишь два моих цента.
В качестве альтернативы: Если у вас есть контроль над XML, вы можете сделать что-то вроде:
<processSettings>
<processName>chrome.exe</processName>
<location>L1</location>
<watch>true</watch>
<rules>
<rule>autoStart</rule>
<rule>noMore</rule>
<rule>unExpectedCrush</rule>
</rules>
</processSettings>
и десериализовать его в список правил:
(List<Rule>)deserializer.Deserialize(config.Rules.CreateReader());
И тогда у вас есть список правил, которые можно перевести в интерфейсную версию.
Но это меняет XML, так что предполагается, что вы можете контролировать это.
Редактировать: List<Rule>
до List<IRule>
Так что, если вы можете получить список List<Rule>
и Rule имеет соответствующий интерфейс. Тогда вы можете преобразовать свой List<Rule>
:
List<Rule> rules = new List<Rule>();
List<IRule> iRules = rules.ToList<IRule>();
Получено из этого ответа Ответ StackOverflow
EDIT2: Сериализация XElement в список правил:
Хорошо, так что мне все еще трудно понять, почему вам нужно отобразить эти правила в объект вместо правила со значением. Я бы сказал, что список правил, содержащих строку, в которой указано, какое это правило, облегчит вашу жизнь. Тогда вам просто нужно сравнить строки, чтобы увидеть, какие у вас правила.
Итак, я думаю, что это решит вашу проблему:
public List<IRule> GetListOfRules()
{
var rulesElement = XElement.Parse(@"<rules>
<autoStart></autoStart>
<noMore></noMore>
<unExpectedCrush></unExpectedCrush>
</rules>");
var listOfRulesFromElement =
rulesElement.Elements().Select(d => new Rule { RuleName = d.Name.LocalName }).ToList<IRule>();
return listOfRulesFromElement;
}
public class Rule : IRule
{
public string RuleName { get; set; }
public string GetRule()
{
return RuleName;
}
}
public interface IRule
{
string GetRule();
}
С этим кодом у вас нет жесткой связи между вашей структурой и правилами. Вы можете просто добавить новые правила в свой элемент XML, и он будет автоматически добавлен в ваш список правил. Затем вы можете просмотреть список правил и посмотреть, какие правила существуют на основе RuleName
. Я надеюсь, что это то, что вы хотите.
Редактировать 3 : типизированное отображение:
Если вам нужно типизированное отображение, я предлагаю перечисление:
public List<IRule> GetListOfRules()
{
var rulesElement = XElement.Parse(@"<rules>
<autoStart></autoStart>
<noMore></noMore>
<unExpectedCrush></unExpectedCrush>
</rules>");
var listOfRulesFromElement =
rulesElement.Elements().Select(d =>
{
var parsed = Enum.TryParse(d.Name.LocalName, out RuleType ruleName);
if (!parsed)
ruleName = RuleType.UnmappedRule;
return new Rule {RuleName = ruleName};
}).ToList<IRule>();
return listOfRulesFromElement;
}
public class Rule : IRule
{
public RuleType RuleName { get; set; }
public RuleType GetRule()
{
return RuleName;
}
}
public enum RuleType
{
UnmappedRule,
AutoStart,
NoMore,
UnExpectedCrush
}
public interface IRule
{
RuleType GetRule();
}