在参数上按基类初始化传递类?

时间:2018-10-16 07:57:29

标签: c# .net oop

我有这样的班级:

public class BaseClass
{
    public int Id { get; set; }
    public void MethodOfBase(){}
}
public class Deliver1 : BaseClass
{
    public string Name { get; set; }
}
public class Deliver2 : BaseClass
{
    public string ClassName { get; set; }
}
public class Deliver3 : BaseClass
{
    public int Age { get; set; }
}

我有一些代码:

    public void Method1()
    {
        Deliver1 deliver1 = null;
        MethodWithBaseClass(deliver1);

        Deliver2 deliver2 = null;
        MethodWithBaseClass(deliver2);

        Deliver3 deliver3 = new Deliver3();
        MethodWithBaseClass(deliver3);


    }

    public void MethodWithBaseClass(BaseClass baseClass)
    {
        if(baseClass == null)
            baseClass = ???
    }

我想初始化投放 但我不想这样检查:

    public void MethodWithBaseClass(BaseClass baseClass)
    {
        if (baseClass == null && baseClass is Deliver1)
            baseClass = new Deliver1();
        else if.....
    }

因为检查过多。 可能吗?以及如何做?

非常感谢您!

2 个答案:

答案 0 :(得分:4)

您编写的代码无法使用,因为if (baseClass == null && baseClass is Deliver1)将始终返回false。那是因为检查null引用上的类型不起作用(它检查值,而不是后备变量类型)。

在这种情况下,您必须使用泛型(和ref),但我认为这不是一个特别好的设计:

public void MethodWithBaseClass<T>(ref T instance) where T : new()
{
    if (instance == null)
    {
        instance = new T();
    }
}

用法:

Deliver1 deliver1 = null;
MethodWithBaseClass(ref deliver1);

答案 1 :(得分:0)

似乎您只是在使用传递的实例来获取其类型并创建该类型的新实例。对我来说这很奇怪。

除此之外,您还要混合两件事:初始化假定您已经已创建实例,如您当前的代码一样。您可以将该实例传递到您的方法中并修改它的属性或字段,但是您不能更改该实例(除非您使用ref-关键字)。相反,您似乎想要的是将类型传递给方法,然后让该方法创建该类型的新实例。

public BaseClass MethodWithBaseClass(Type baseClass)
{
    return (BaseClass) Activator.CreateInstance(baseClass);
}

现在这样称呼:

var newInstance = MethodWithBaseClass(typeof(Derived1));

如果您提供的类型不继承自InvalidCastException,则当然会抛出BaseClass。这意味着您将失去强类型,这意味着您编译时不知道从该方法获得的确切类型。您还可以使方法通用:

public T MethodWithBaseClass<T>() where T: BaseClass, new()
{
    return new T();
}

并这样称呼它:

var newInstance = MethodWithBaseClass<Derived1>();

这可以实现强类型化,但是假定您在编译时知道确切的类型。