В c# есть ли способ написать универсальный такой объект: Object?
Есть ли способ сделать что-то подобное в c#? Рассмотрим следующий пример и предположим, что Child1, Child2, Child3-все дети Parent -
class Class1
{
SomeObject< Parent > mSomeObject;
Class1()
{
if (condition1)
mSomeObject = new SomeObject<Child1>();
else if (condition2)
mSomeObject = new SomeObject<Child2>();
else if (condition3)
mSomeObject = new SomeObject<Child3>();
}
}
Идея состоит в том, что этот Class1 будет иметь SomeObject в качестве члена, но до времени выполнения неизвестно, какую универсальную форму SomeObject он должен принять. Любая помощь будет оценена по достоинству. Спасибо!
4 ответов:
Следует использовать наследование на основе интерфейса. Это позволит child1, child2 и child3 быть полиморфными и принимать характеристики родителя без необходимости такой логики защиты. С помощью тестов IF ваш код станет более читаемым и его будет легче изменить позже.
Вот пример, который я только что написал С LINQPad, чтобы показать это в действии.
public interface ICar { bool IsAutomatic(); } public class Silverado : ICar { public bool IsAutomatic() { return true; } } public class Semi : ICar { public bool IsAutomatic() { return false; } } void Main() { ICar car = new Silverado(); bool isAuto = car.IsAutomatic(); isAuto.Dump(); car = new Semi(); isAuto = car.IsAutomatic(); isAuto.Dump(); }Вывод:
True FalseЯ предпочитаю наследование на основе интерфейса в отличие от абстрактных классов, описанных Алленгом. Причины, такие как множественное наследование - класс может реализовать много интерфейсов, но наследовать только от 1 класса.
Надеюсь, это поможет...
Вы могли бы сделать это. Обратите внимание на использование ключевого слова
outздесь, чтобы сделать тип ковариантным.public interface ISomeObject<out T> { }Однако это несколько ограничит то, что вы можете сделать с
Tв интерфейсе. В частности, вы можете объявлять члены только там, гдеTнаходится в выходной позиции. Другими словами, он не может быть принят в качестве параметра функции.
Я никогда не пробовал этого, но я верю, что вы правы. В общем случае, если
public class Child : ParentТогда любой вызов
Parentбудет удовлетворенChild.Например:
public class Animal { //stuff } public class Cat : Animal { // overridden stuff } List<Animal> pets = new List<Animal>; pets.Add(new Cat());Сработает.
Если вы ищете поведение, вы можете захотеть работать с интерфейсами вместо наследования классов, но это будет работать так же.
Нет, проблема, которую вы можете иметь с вашим подходом, заключается в том, что вашSomeObject<Parent>будет иметь доступ только к тем членам в вашем родительском классе. Использовать все, что находится в соответствующем дочернем классе, вам нужно будет вернуть в соответствующий дочерний класс.
Это можно сделать в C# 4.0 с интерфейсом или делегатом, но не с классом. Рассмотрите возможность изменения свойства на тип интерфейса и прочтите больше о ковариации и контравариации универсалий в C# 4.0 (например, здесь: http://msdn.microsoft.com/en-us/library/ee207183.aspx )
Comments