【问题标题】:Adopt method parameters from constructor从构造函数中采用方法参数
【发布时间】:2014-03-11 23:36:23
【问题描述】:

我有一些需要大量参数的类。我刚刚创建了一个带有两个参数的示例来演示我的问题。

public class Zoo
{
    public List<Animal> Animals { get; set; }

    public Zoo()
    {
        Animals = new List<Animal>();
    }

    // Pass all parameters
    public void AddAnimal(string name, int age)
    {
        Animals.Add(new Animal(name, age));
    }

    // -> pseudo code <- Create the parameter reference automated -> pseudo code <-
    public void AddAnimal(params ...)
    {
        Animals.Add(new Animal(...));
    }
}

public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Animal(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

如果我想将Animal 添加到我的Zoo,我有两个选择。

  1. 将所有参数传递给AddAnimal 方法
  2. Animal 对象添加到List

正如我所说,我有很多参数和很多“动物”。

是否可以在不手动添加到 AddAnimal 方法的情况下引用 Animal 构造函数的参数? (参见:第一个代码块中的-&gt; pseudo code &lt;-

但我想保留方法调用。

Zoo zoo = new Zoo();
zoo.AddAnimal("Tom", 8);

提前致谢, 一月

编辑: 出于某种原因,我想阻止使用以下方法之一:

zoo.AddAnimal(new Animal("Ben", 9));
zoo.AddAnimal(new Animal { "Ben", 9 }); // With empty constructor...

那么,最后一个问题是:是否可以只使用only构造函数参数而不将它们c&p到方法中?

【问题讨论】:

  • 您的 param object[] 方法可能是您自动代理参数(运行时类型检查和装箱交易)所能获得的全部...阅读factory 模式,因为它可能是您想要的实现...或者可能是 t4(用于代码生成的 VS 模板...)

标签: c# generics methods parameters constructor


【解决方案1】:

不,您不能自动代理所有单独的构造函数参数。但是您可以将负担转移给调用者:

public void Add(Animal animal)
{
    if(animal == null) throw new ArgumentNullException("animal");
    Animals.Add(animal);
}
...
zoo.Add(new Animal("Fred", 27));

或者您可以按照“传递所有参数”示例手动复制/粘贴签名/构造函数调用。

【讨论】:

  • 没错,谢谢。但是,我想防止在“动物园”类之外创建对象。正如我所说,我有很多具有更多参数的动物。不能只传递泛型参数吗?谢谢!
  • @Jan 不,不是;此外,使用如图所示的结构,调用者已经可以绕过所有内容:zoo.Animals.Add(new Iguanodon());(显然是Iguanodon : Animal
  • +1 您无法获得所有参数的自动通用代理和编译时类型检查...
  • @AlexeiLevenkov 好吧,你可以。但你没有。
【解决方案2】:

我觉得基本思路应该是这样的:

public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public override string ToString()
    {
        return "[" + Name + ", " + Age + "]";
    }
}

public class Zoo
{
    public List<Animal> Animals { get; set; }

    public Zoo()
    {
        Animals = new List<Animal>();
    }

    // Pass all parameters
    public void AddAnimal(string name, int age)
    {
        Animal animal = new Animal
        {
            Name = name,
            Age = age
        };

        Animals.Add(animal);
    }

    // -> pseudo code <- Create the parameter reference automated -> pseudo code <-
    public void AddAnimal(params object[] animalProperties)
    {
        Animal animal = new Animal
        {
            Name = animalProperties[0] as string,
            Age = (animalProperties[1] as int?).Value
        };

        Animals.Add(animal);
    }
}

public class Example
{
    public void Run()
    {
        Zoo zoo = new Zoo();
        zoo.AddAnimal("Tom", 8);

        foreach (Animal a in zoo.Animals)
        {
            Console.WriteLine(a.ToString());
        }
    }
}

但是您可以这样做的最好方法是将通用对象而不是特定类型传递给您的方法,在我看来这不是一个好主意(除非您真的确定您之前已经对它们进行过类型检查)

另一个建议:如果您有很多属性,如您所说,请避免实现构造函数。我认为不必处理它更易于管理(特别是如果某些属性可以为空)。

【讨论】:

  • 谢谢。那是可能的,但我需要一个类型安全的解决方案。因为所有参数都是必要的。此外,(这里称为)Zoo 类只是用来保存数据。它实际上没有任何逻辑。无论如何:感谢您的回答。
猜你喜欢
  • 2011-04-11
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 2014-05-09
  • 1970-01-01
相关资源
最近更新 更多