В 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 он должен принять. Любая помощь будет оценена по достоинству. Спасибо!

559   4  

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

    Ничего не найдено.