Same property name, but different return type in the general list

Asked question: how to implement a common list List<Item>return elements with the Data property, but return different types for different subclasses? I began to create the following hierarchy, but this does not lead to the goal.

abstract class Item
abstract class ItemGeneric<TData> : Item
class ItemText : ItemGeneric<string>
class ItemImage : ItemGeneric<Image>

I create a bunch of instances of the ItemText and ItemImage classes and add them to the general List<Item>list. However, as soon as I look through the list and want to get the Data property, it is not available (obviously), it was implemented only at the level of the class hierarchy ItemGeneric<TData>, and not in the Item class.

I would like to solve this problem without using System.Objectto avoid casting.

Is there a common template to solve this problem?

+3
4

, 100%, .

:

interface IUntypedItem
{
  object UntypedData {get; }
}

interface IItem<T> : IUntypedItem
{
  T Data {get; set;}
}

class abstract ItemGeneric<T> : IItem<T>
{
  T Data { get; set; }
  object UntypedData { get { return Data; }}
}

class ItemText : ItemGeneric<string>
{

}

UntypedItems

List<IUntypedItem> list;
foreach (IUntypedItem item in list)
{
  // use item.UntypedData
  // or downcast to use typed property
}

, . , .

+1

, , upfront.

:

foreach (Item item in list)
{
    ItemGeneric<int> intItem = item as ItemGeneric<int>;
    if (intItem != null)
    {
        //do stuff
    }
}

, , .

(. encapsulation)

, :

foreach (Item item in list)
{
    item.DoStuff();
}

, DoStuff Item:

public abstract class Item
{
    public abstract void DoStuff();
}

.. ItemGeneric:

public class ItemGeneric<T> : Item
{
    public T Data { get; set; }

    public override void DoStuff()
    {
        //do generic typed stuff here
        Console.WriteLine(Data);
    }
}
+1

- ?

public class ItemGeneric<T> {

  private List<T> data;

}

public class ItemText : ItemGeneric<String> { ... }

public class ItemImage : ItemGeneric<Image> { ... }

Java T, , #

public class ItemGeneric<T extends IData> {

 private List<T> data;
}
0

This is how you create a function in BaseClass that returns a DerivedTypes collection when called from an object of a derived class type, without the magic of only Generics. This example talks about a HashSet, in your case it can be any type that you want.

//**The BaseClass**
public class BaseClass<T>
    where T : BaseClass<T>
{
    public HashSet<T> GetHashSet()
    {
        HashSet<T> hSet = new HashSet<T>();
        //create a HashSet<T>
        //do some work
        //and return;
        return hSet;
    }
}

//**The Derived Class**
public class DerivedClass : BaseClass<DerivedClass>
{
    //you have the method inherited.
}
0
source

Source: https://habr.com/ru/post/1723991/


All Articles