将基类动态转换为派生类

时间:2018-07-14 17:32:49

标签: c# casting derived-class

对于不喜欢阅读大量伪代码的人:

我想基于变量将基类动态转换为派生类,然后使用此新转换的派生类而无需进行大量转换。这是否有可能,如果可以的话,我该怎么做?

我要使用伪代码执行的操作:

我有一个像这样的基本架构:

// Base Class:

class BaseClass
{
    public BaseClass(string data)
    {
        Data = data;
    }

    public string Data { get; set; }
}

// Interface for derived Classes:

interface IStuff
{
    void DoStuff();
}

// Derived Classes: 
// (Don't have own Properties besides the ones they get from BaseClass and 
// no other Methods than they have to implement from IStuff)

class DerivedClass1 : BaseClass, IStuff
{
    public void DoStuff()
    {
        Console.WriteLine($"1: {Data}");
    }
}

class DerivedClass2 : BaseClass, IStuff
{
    public void DoStuff()
    {
        Console.WriteLine($"2: {Data}");
    }
}

现在最棘手的部分:我希望能够执行以下操作:

UnknownType GetDerivedClass(BaseClass baseClass, int value)
{
    switch(value)
    {
        case 1:
        return baseClass as DerivedClass1;
        case 2:
        return baseClass as DerivedClass2;
        default:
        return null;
    }
}

var value = 1;
var baseClass = new BaseClass("data here");

var derivedClass = GetDerivedClass(baseClass, value);

derivedClass.DoStuff(); // prints "1: data here"

在这种情况下,如果我将'value'变量更改为2,它将打印“ 2:这里的数据”。是否有可能以某种方式使自己不致丧命,或者您是否还有另一种架构选择可以使我尝试做的事情容易得多?

2 个答案:

答案 0 :(得分:0)

#--- noise removal ---
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(otsu_th, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations = 2)

#--- sure background area ---
sure_bg = cv2.dilate(opening, kernel, iterations = 1)
cv2.imshow('sure_bg', sure_bg)

#--- Finding sure foreground area ---
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.1 * dist_transform.max(), 255, 0)

cv2.normalize(dist_transform, dist_transform, 0, 1, cv2.NORM_MINMAX, dtype=cv2.CV_32F)
#cv2.imshow('dist_transform_normalized', dist_transform)
#cv2.imshow('sure_fg', sure_fg)

#--- Finding unknown region ---
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(opening, sure_fg)
cv2.imshow('unknown', unknown)

答案 1 :(得分:0)

这就像您要基于url或在编译时知道的任何信息实例化派生类(因为您使用的是switch case块并根据已知值返回类)。

您可以在基类中使用字典。例如:

Dictionary<int,Func<BaseClass>> DerivedClasses ={
    [1] = ()=> new DerivedClass1(),
    [2]= () => new DerivedClass2()
    };

当然,您将所需的行为封装在每个派生类中。

现在GetDerivedType(int value)应该在BaseClass中,并且只会返回

if (DerivedClasses.TryGetValue(value, out var derivedClass))
    return derivedClass;

return null;