How to create and set a polymorphic property?

I want to create a class that can use various properties in a property. I try to do this with polymorphism, but I have not yet learned how to do it right, therefore, my request for advice.

I have a base class and two classes that inherit it:

public abstract class BaseClass
{
    public string Name { get; set; }
    public Unit Unit { get; set; }
}

public class DerivedClassFloat : BaseClass
{
    public float Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

public class DerivedClassString : BaseClass
{
    public string Value { get; set; }

    public override string ToString()
    {
        return Value;
    }
}

Everything is fine, I can create a list and add various specialized subclasses. My problem occurs when I need to change the values ​​of elements in my list:

foreach (var item in ListOfBaseClasses)
{
   if(item is DerivedClassFloat)
     ((DerivedClassFloat) item).Value = float.NaN;
   if (item is DerivedClassString)
      ((DerivedClassString) item).Value = string.Empty;
}

According to what I read, it looks like the smell of code. Is there a better way to access the value property of my derived classes based on the type I'm trying to assign?

How about when you want to create the correct subclass based on value?

BaseClass newClass = null;
if (phenotype is DerivedClassFloat)
    newClass = new DerivedClassFloat(){Value = 12.2};
if (phenotype is DerivedClassString)
    newClass = new DerivedClassString(){Value = "Hello"};                      

, , , ... , - ?


, , .

, . , . :

public class Organism
{
    public string Name { get; set; }
    public List<Attribute> Attributes { get; set; }
}

public class Attribute
{
    public string AttributeName { get; set; }
    public object AttributeValue { get; set; }
}

, . , . , , , , If.. , .

+5
6

reset Value, ResetValue , .

, , , Factory Prototype.

+2

Generics :

public abstract class BaseClass<T>
{
    public string Name { get; set; }
    public Unit Unit { get; set; }
    public T Value { get; set; }
}

public class DerivedClassFloat : BaseClass<float>
{
    public override string ToString()
    {
        return Value.ToString();
    }
}

public class DerivedClassString : BaseClass<string>
{
    public override string ToString()
    {
        return Value;
    }
}
+2

generics , Value :

public abstract class BaseClass<T>
{
    public string Name { get; set; }
    public Unit Unit { get; set; }
    public T Value { get; set; }

    public override string ToString()
    {
        return Value.ToString();
    }
}

public class DerivedFloat : BaseClass<float> {}

public class DerivedString : BaseClass<string> {}
+1

. , , , .

. - .

public void setValue(string val, Type type);//move this to your base class

    Class MyValue{
private string strVal;
private int intVal;

//constructor
MyValue(string val, Type type){
     //check the type enum here and set the values accordingly
}
}

then when set values
foreach (var item in ListOfBaseClasses)
{
     item.setValue = MyValue("",Type.INT);
}
+1

, - Value , Value , , , , .

Value, , , object - , . NullObject , Value .

0

You can use abstract factory template . Consider this example:

// Base class

class Button
{
    protected Button()
    {
    }

    public string Name { get; set; }
}

// Factory interface

public interface ButtonFactory
{
    Button CreateButton();
}

// And the concrete classes

class WindowsButton : Button
{
    // ...
}

class WindowsButtonFactory : ButtonFactory
{
    public Button CreateButton()
    {
        return new WindowsButton();
    }
}

class MacButton : Button
{
    // ...
}

class MacButtonFactory : ButtonFactory
{
    public Button CreateButton()
    {
        return new MacButton();
    }
}

In addition, you can combine an abstract factory template with a strategy to encapsulate custom behaviors that change with the type.

0
source

All Articles