2015-07-21 3 views
0

Следующие коды работают как есть, но я хотел бы использовать ссылку на класс MyProperty, который должен быть передан в конструкторе вместо строго типизированных ссылок во встроенном коде.C# передать класс аргументу конструктору

Как это сделать, я должна пройти реф в MyProperty, но все, что я пытался не удается

Я хотел PropertyClass, чтобы быть в состоянии обрабатывать любые классы MyProperty т.е. не ссылки на MyProperty в PropertyClass

Все еще учиться так жаль, если я пропустил очевидное!

Большое спасибо за любую помощь

Сара

PropertyClass pc = new PropertyClass(!here!); // Would like to pass MyProperty class here 

pc.Settings.Add(new MyProperty("Fred", "Monday")); 
pc.SaveXml("MyTest.xml"); 




public class MyProperty 
{ 
    [XmlAttribute] 
    public string MyPropName { get; set; } 
    [XmlElement] 
    public string MyPropData { get; set; } 

    // default constructor needs to be parameterless for serialisation. 
    public MyProperty() 
    { 
    } 

    public MyProperty(string Name, string Data) 
    { 
     MyPropName = Name; 
     MyPropData = Data; 
    } 
} 



public class PropertyClass 
{ 
    public List<MyProperty> Settings { get; set; } 

    public PropertyClass()    // How to pass the required class here ? 
    {         // public PropertyClass(ref MyProperty myprop) 
     Settings = new List<MyProperty>(); 
    } 

    public void SaveXml(string fileName) 
    { 
     using (FileStream stream = new FileStream(fileName, FileMode.Create)) 
     { 
      XmlSerializer XML = new XmlSerializer(typeof(List<MyProperty>), new XmlRootAttribute("Settings")); 

      XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
      namespaces.Add(string.Empty, string.Empty); 

      XML.Serialize(stream, Settings, namespaces); 
     } 
    } 
} 
+0

Вы пытаетесь передать только тип объекта, который вы хотите хранить в экземпляр «PropertyClass»? Вы пробовали использовать дженерики? Или вопрос о проблемах сериализации с дженериками? –

+1

Я думаю, что вы ищете [Generics] (https://msdn.microsoft.com/en-us/library/512aeb7t.aspx)? ... –

+0

Привет Большое спасибо за ответ. Я надеялся, что который может обрабатывать любой класс стиля MyProperty, который передается ему. класс MyProperty может состоять из любого количества объектов, а сериализация поставляемого класса является основной частью. Короче говоря, я просто не хочу иметь PropertyClass для всех требований MyProperty, также мне нужно полностью понять, почему то, что я пытаюсь сделать, не работает !!! –

ответ

2

Я хотел бы изменить определение PropertyClass к

public class PropertyClass<T> 
{ 
    public List<T> Settings { get; set; } 

    public PropertyClass() 
    { 
     Settings = new List<T>(); 
    } 

    public void SaveXml(string fileName) 
    { 
     using (FileStream stream = new FileStream(fileName, FileMode.Create)) 
     { 
      XmlSerializer XML = new XmlSerializer(typeof(List<T>), new XmlRootAttribute("Settings")); 

      XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(); 
      namespaces.Add(string.Empty, string.Empty); 

      XML.Serialize(stream, Settings, namespaces); 
     } 
    } 
} 

type parameterT определяет тип элементов в List<T>, так что вы можете создать экземпляр PropertyClass следующим образом:

var pc = new PropertyClass<MyProperty>(); 

Или, когда вы устали от MyProperty, вы можете изменить его на new PropertyClass<foo>(), не меняя его в другом месте.

Еще одна приятная особенность, которая мне нравится дженериков является то, что вы можете поставить ограничения на параметр типа в строке, где вы объявляете это нравится:

public class PropertyClass<T> where T : MyClass, IMyInterface, new() 

Это означает, что T должен быть получен из MyClass, он должен реализовать IMyInterface и должен иметь конструктор без параметров.(Очевидно, вам не нужно добавлять все такие ограничения, но в некоторых случаях они могут быть полезны).

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

+0

Wow Спасибо, что это быстро, мне нужно немного времени, чтобы поглотить то, что вы сказали, но я думаю, что понимаю, что вы сказали (удивил себя!), Мне действительно не нравится делать то, что я не понимаю, Мне нравится делать аккуратный код, который понятен через 5 лет. Кстати, я перехожу от Forth к C#, поэтому не имею в виду подвиг. Спасибо за помощь, которую по достоинству оценили. –

+0

Namelesss One Thanks generics достигает именно того, что мне нужно, я отметил ваш ответ как принятый. Большое спасибо за великолепное объяснение. –

0

это, как вы вызываете конструктор

PropertyClass pc = new PropertyClass(new MyProperty("Fred", "Monday")); 

Это конструктор

Public MyProperty MyProperty { get; set; } 
public PropertyClass(MyProperty _myProperty) 
{ 
    MyProperty = _myProperty 
} 
+1

Вы должны улучшить качество этого ответа, добавив пояснительную информацию. ТАК хмурится ответами на код. –

+0

@WilliamCustode это код, чтобы просто подключиться к вопросу – Paparazzi

0

Вам нужно добавить const uctor, который принимает MyProperty в качестве аргумента:

public PropertyClass(MyProperty myprop)    
{         
    Settings = new List<MyProperty> {myprop}; 
} 

Обратите внимание, что MyProperty является ссылочным типом, так ref ненужно здесь (это уже это ссылка).

+0

Я пробовал это, но как дозировать сериализацию пройденного класса, забрать его ссылку. Я чувствую, что здесь отсутствует какая-то важная концепция. Мне нужен класс, чтобы быть самодостаточным, чтобы иметь возможность обрабатывать многие разные классы «MyProperty», которые будут иметь разные конфигурации. Итак, если я использую приведенное выше, как класс сериализации использует вышеупомянутую концепцию? –

1

Я думаю, вам нужен общий класс.

public class PropertyClass<T> 
{ 
    public List<T> Settings { get; set; } 

    public PropertyClass() 
    { 
    Settings = new List<T>(); 
    } 
... 
} 

PropertyClass<MyProperty> pc = new PropertyClass<MyProperty>(); 

Я должен добавить, что ваше именование очень неясно. PropertyClass следует называть что-то вроде XmlableList. И MyProperty уже существует и называется NameValuePair<string,string>

+0

Извините за именование, я пытался сделать то, что делал просто, явно не получилось, но я слушал то, что вы сказали. Many Thanks –

1

Возможно, вы ищете дженериков:

public class PropertyClass<TMyProperty> 
{ 
    public List<TMyProperty> Settings { get; set; } 

    public PropertyClass() 
    {         
     Settings = new List<TMyProperty>(); 
    } 
    .. 
} 
1

Работайте над своим наименованием, не сразу стало очевидно, что PropertyClass фактически представляет собой набор свойств; возможно, MyPropertyCollection будет лучше?

То, что вы ищете, называется перегрузкой конструктора. В принципе можно указать конструктор снова, но на этот раз с параметрами:

public MyPropertyCollection() 
{ 
    Settings = new List<MyProperty>(); 
} 
public MyPropertyCollection(IEnumerable<MyProperty> collection) 
{ 
    Settings = new List<MyProperty>(collection); 
} 

Или позволить var col = new MyPropertyCollection(new MyProperty(), new MyProperty(), new MyProperty()) вы можете сделать:

public MyPropertyCollection(params MyProperty[] collection) 
{ 
    Settings = new List<MyProperty>(collection); 
} 

Хотя вы должны быть осторожны с тем, он не чувствует себя хорошо и если вы позже захотите ввести дополнительные параметры, хорошо это может закончиться плохо.

Кроме того, как вы в основном упаковка список, что вы могли бы также рассмотреть это System.Collection.ObjectModel.Collection<T> класс как основа:

// The Collection<MyProperty> base class is responsible for maintaining the list 
public class MyPropertyCollection : Collection<MyProperty> 
{ 
    public MyPropertyCollection() 
    { 
     // Default base() constructor is called automatically 
    } 

    public MyPropertyCollection(IList<MyProperty> properties) 
     : base(properties) 
    { 
     // Overloaded constructor calls base constructor with collection of properties 
    } 

    public void SaveXml(string fileName) 
    { 
     using (var stream = new FileStream(fileName, FileMode.Create)) 
     { 
      // Serializer should now target this very class 
      var xml = new XmlSerializer(typeof (this), new XmlRootAttribute("Settings")); 

      var namespaces = new XmlSerializerNamespaces(); 
      namespaces.Add(string.Empty, string.Empty); 

      xml.Serialize(stream, this, namespaces); 
     } 
    } 
} 
+0

Извините, это было вызвано MypropCollection, но поскольку я не использовал коллекции, я изменил его имя, чтобы задать вопрос. Я искренне благодарю вас за ваш ответ и теперь вам нужно переварить то, что вы сказали, мне нужно понять, почему и что я делаю, и, как вы можете догадаться, это небольшая часть гораздо более масштабного проекта, предыдущее кодирование все в одном так что все это несколько отличается. Посвященная Сара –

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