Nick4978 Ответов: 1

Как добавить универсальное свойство другого класса<T & gt; внутри существующего класса< T>


Не совсем уверен, как объяснить это в одной строчке, но вот моя ситуация.

У меня есть абстрактный базовый класс под названием "Deal", который имеет свойство в нем, которое относится к классу " Inventory"

Теперь сделка может быть либо наличной, финансовой, арендной, оптовой или арендной, поэтому она относится к типу сделки. Он также абстрактен, поскольку каждый из типов сделок имеет некоторые свойства, которые не применяются к другим, но все они имеют набор общих свойств, поэтому различные типы сделок (например, финансы, аренда и т. д.) наследуются от базового класса Deal и имеют свои собственные добавленные методы и свойства.

То же самое относится и к другому абстрактному классу "инвентаря". Инвентарь может быть таким, как автомобиль, грузовик, лодка, фургон и т. д.), Поэтому у меня есть класс инвентаря.

Вот в чем проблема:

Сделка должна содержать единицу в запасе. Например, вы финансируете автомобиль или арендуете фургон, а затем заключаете сделку с инвентарным имуществом типа инвентаря или каким-либо другим случаем.

Когда я создаю класс Deal и добавляю к нему свойство типа SoldUnit as Type Inventory, T наследуется от класса Deal. Как я могу создать универсальное свойство типа Inventory внутри класса Deal?

Deal на самом деле не будет работать из-за большого количества возможностей, так как же я могу создать универсальное свойство "SoldUnit", которое ссылается на класс инвентаря внутри класса Deal? А при сохранении строгой типизации? Я знаю, что мог бы создать свойство SoldUnit с типом object или dynamic, но есть ли лучший способ?

Вот выдержка из кода: он не работает, потому что тип T уже является DealType, но это два свойства [ ret.Vehicle = new Car(); и ret.SoldUnit = new Car ();], которые я пытаюсь заполнить определенным типом инвентаря (автомобиль, грузовик, rv, лодка и т. д.) В методе Get (). Конкретный тип запасов определяется флагом в поле база данных.

public abstract class Deal<T>
{
    public string Uid { get; set; } = Guid.NewGuid().ToString();
    public DealTypes DealType { get; set; } = DealTypes.Finance;

    public Buyer Customer { get; set; }
    public Inventory<T> Vehicle { get; set; }
    public Location Location { get; set; }
    public Inventory<T> SoldUnit { get; set; }

    public abstract T Add(string id);
    public abstract T Update(string id);
    public abstract T Get(string id);
}

public abstract class Inventory<T>
{
    public string Uid { get; internal set; } = Guid.NewGuid().ToString();
    public Location Location { get; set; }
    public string StockNumber { get; set; } = "";
}

public class Cash : Deal<Cash>
{
    public decimal TradeAllowance { get; set; }
    public decimal TradePayoff { get; set; }
    public decimal TotalDown { get; set; }
    public decimal DueOnDelivery { get; set; }

    public override Cash Get(string id)
    {
        var ret = new Cash();
        ret.Customer = new Buyer();
        ret.Vehicle = new Car();
        ret.Location = new Location();
        ret.SoldUnit = new Car();
   }
}

public class Car : Inventory<Car>
{
    public decimal GrossWeight { get; set; }
    public decimal NetWeight { get; set; }
    public string Branded { get; set; } = "";
    public string FuelType { get; set; } = "";
    public string Trim { get; set; } = "";
    public string Body { get; set; } = "";
    public int Cylinders { get; set; }
    public decimal EngineSize { get; set; }
    public string TransmissionType { get; set; } = "";
    public string Suspension { get; set; } = "";
    public string InteriorColor { get; set; } = "";

    public bool OdometerExceedsLimit { get; set; }
    public bool OdometerTrueMileageUnknown { get; set; }
    public bool OdometerFiveDigit { get; set; }


    public string TitleNumber { get; set; } = "";
    public DateTime? TitleDate { get; set; }
    public string TitleState { get; set; } = "";
    public DateTime? TitleDue { get; set; }
    public DateTime? TitleReceived { get; set; }
}


Есть ли способ сделать это?

Спасибо!

Что я уже пробовал:

Я пробовал сделать класс Deal с двумя типами
public class Deal<TDeal, TInventory>
но тогда мне пришлось бы сделать класс для каждой возможной комбинации типа сделки / инвентаря. До сих пор единственное, что я могу придумать, чтобы это сработало, - это сделать свойства Vehicle и SoldUnit типа object или dynamic, но тогда я не получаю строгой типизации или intellisense.

public dynamic Vehicle { get; set; }

public object SoldUnit{ get; set; }

Nick4978

В двух словах, это та часть, которую я пытаюсь заставить работать:

    
    public abstract class Deal<T>
    {
        public Inventory<AnyVehicleType> Vehicle { get; set; }
        public Inventory<AnyVehicleType> SoldUnit { get; set; }
    }


AnyVehicleType это просто psuedo-код здесь, но будет свойством типа Inventory (автомобиль, грузовик, лодка и т. д.) внутри класса сделок, которые могут быть такими вещами, как финансы, аренда, Оптовая торговля и т. д.

Richard Deeming

Зачем нужен параметр универсального типа на Inventory класс? Не похоже, чтобы использоваться где угодно.

Если есть является причина, чтобы иметь его, не могли бы вы создать не универсальный базовый класс?

public abstract class Inventory
{
    public string Uid { get; internal set; } = Guid.NewGuid().ToString();
    public Location Location { get; set; }
    public string StockNumber { get; set; } = "";
}

public abstract class Inventory<T> : Inventory
{
}

1 Ответов

Рейтинг:
0

Richard MacCutchan

Но и сделка, и инвентарь являются абстрактными классами, поэтому вы не можете создать ни один из них. Вы могли бы сделать Deal реальным классом и использовать перечисление, чтобы решить, какой это тип; то же самое с Inventory. И вы не можете сделать что-то вроде

public class Car : Inventory<Car>

Вы не можете создать тип, который еще не определен.

Я думаю, что вы переоцениваете свои занятия.


Nick4978

Но ни сделка, ни инвентарь никогда не должны создаваться сами по себе, потому что сами по себе они ничто. Они имеют только некоторые базовые свойства, которые используются в реальных классах. Например, все объекты инвентаря имеют Uid и какой-то серийный номер, а все сделки имеют проданную единицу и клиента. Даже если я удалил abstract, у меня все равно есть та же проблема с любым типом сделки, имеющим свойство любого инвентаря. Это было бы слишком грязно, чтобы сделать что-то вроде:

public class Deal<T>
{
    public Car SoldCar {get; set; }
    public Truck SoldTruck {get; set; }
    public RV SoldRV {get; set; }
    public Boat SoldBoat {get; set; }
}

и т.д..

Richard MacCutchan

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

abstract class Deal
{
// properties and methods common to all subclasses
};
class Car : Deal // for example
{
int engineCapacity; // a field unique to a Car
};

Nick4978

Может быть, я что-то неправильно понял. Но в вашем примере у вас есть класс Car, который наследуется от Deal. Эти двое совершенно разные. "Автомобиль" - это единица" инвентаря", тогда как" сделка " - это базовый класс Финансовой, лизинговой, кассовой, оптовой и т. д.

Например, я сдаю машину в аренду Джону. Это "Форд-Мустанг" 2014 года выпуска, который я сдаю Джону в аренду за 15 000 долларов.

Теперь у меня есть" арендная " сделка, в которой есть сумма аренды (налог с продаж, сборы и т. д.) как часть сделки, но сделка также содержит клиента (у которого есть имя, адрес, телефон и т. д.), а также автомобиль, который я арендовал у него (у которого есть год, марка, цвет и т. д.)

Так что машина никогда ничего не унаследует от сделки. Сделка должна была иметь ссылку на автомобиль, который был продан. (Как и клиент, которому он был продан.)

Проблема у меня в том, что это может быть автомобиль, или это может быть грузовик, фургон, лодка и т. д. А сама сделка может быть кассовой, арендной, финансовой, оптовой и т. д.

Есть ли смысл в этом примере? Или я все еще не понимаю, что именно вы говорите?

Спасибо!

Richard MacCutchan

Извините, это должен был быть один из финансовых классов, например наличные. Но комментарии по-прежнему остаются в силе.

Nick4978

Окей. Таким образом, если бы я не заставил абстрактный класс иметь дело с типом <T>, то мне пришлось бы избавиться от абстрактных методов, возвращающих конкретный подкласс Deal, и переместить их в подкласс?

т.е. -

public abstract class Deal {       
    ...properties...         
    public abstract T Add();            
    public abstract T Add(string id);            
    public abstract T Update();            
    public abstract T Update(string id);            
    public abstract T Get(string id);            
    public abstract List<T> Find();            
    public abstract bool Delete();            
    public abstract bool Delete(string id);
}

Richard MacCutchan

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