首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多个可初始化字段的类的简化构造器

具有多个可初始化字段的类的简化构造器
EN

Stack Overflow用户
提问于 2015-11-12 11:53:51
回答 2查看 2K关注 0票数 1

我目前有以下问题:

我有一个包括三个不同字段的类

  • 恩姆x
  • ActiveDirectoryUser y
  • CustomClass z

枚举可以通过传递字符串或枚举对象来初始化。ADUser可以通过传递字符串(LoginName)来初始化,也可以通过用户本身来初始化,CustomClass可以通过传递字符串、int或对象来初始化。

现在,我想初始化类以传递所有不同的组合,如

代码语言:javascript
复制
class(string enumValue, string adUser, string customClass) 
class(string enumValue, ADUser adUser, CustomClass customClass)
class(EnumValue enumValue, string adUser, CustomClass customClass)

有没有一种方法可以简化构造函数而不键入所有12种可能性(Enum-2 * ADUser-2 * CClass-3 = 12)?

我想到了链式构造函数,其中我还得到了12个构造函数,但我也考虑过只在每个参数上传递c#对象,并对其进行转换和处理,但我认为这只是一个肮脏的解决方法?

编辑

类包含在库中,因此可以在内部使用,也可以用于公共的。对于内部用途,传递对象的具体版本没有问题。但是,如果我在其他解决方案中使用它,这些解决方案只能引用字符串或int值。因此,类应该能够“获取”值并在初始化时转换它们,因为它可以访问所有真实的对象。

也许这能澄清一些问题。

这里有一些更改名称的代码片段:

代码语言:javascript
复制
#region Content of libraryOne

public class ClassName
{
    internal EnumValueWrapper { get; set; }
    internal CustomClass { get; set; }
    internal ADUser { get; set; }

    public ClassName() { ... } //Now via Builder Pattern
    internal ClassName() { ... } //With Parameters for internal initialisations

    public InformationContainer GetContentInfo()
    {
        //[...]Process Stuff and Return Container
    }
}

internal CustomClass { ... }
internal EnumValueWrapper { ... }
internal ADUser { ... }

#endregion Content of libraryOne
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-12 12:36:23

我认为最好的做法是使用Builder模式。您甚至可以在派生类中使用它。

我要建的课程:

代码语言:javascript
复制
public class MyBaseClass
{
    public MyBaseClass(SomeEnum enumValue, User user)
    {
    }
}

public class MyDerivedClass : MyBaseClass
{
    public MyDerivedClass(SomeEnum enumValue, User user, CustomClass customStuff)
        : base(enumValue, user)
    {
    }
}

现在,让我们添加一个构建器类,其中包含一个额外的扩展类,以使事情变得更舒适(这是一种使用C#扩展方法的扩展生成器模式):

代码语言:javascript
复制
public class MyBaseClassBuilder
{
    public SomeEnum EnumValue { get; set; }

    public User User { get; set; }
}

public static class MyBaseClassBuilderExtensions
{
    public static T SetEnumValue<T>(this T instance, SomeEnum value)
        where T : MyBaseClassBuilder
    {
        instance.EnumValue = value;
        return instance;
    }

    public static T SetEnumValue<T>(this T instance, string value)
        where T : MyBaseClassBuilder
    {
        instance.EnumValue = (SomeEnum)Enum.Parse(typeof(SomeEnum), value);
        return instance;
    }

    public static T SetUser<T>(this T instance, User value)
        where T : MyBaseClassBuilder
    {
        instance.User = value;
        return instance;
    }

    public static T SetUser<T>(this T instance, string value)
        where T : MyBaseClassBuilder
    {
        instance.User = new User(value);
        return instance;
    }

    public static MyBaseClass Build(this MyBaseClassBuilder instance)
    {
        return new MyBaseClass(instance.EnumValue, instance.User);
    }
}

现在,让我们对派生类执行同样的操作:

代码语言:javascript
复制
public class MyDerivedClassBuilder : MyBaseClassBuilder
{
    public CustomClass CustomStuff { get; set; }
}

public static class MyDerivedClassBuilderExtensions
{
    public static T SetCustomStuff<T>(this T instance, CustomClass value)
        where T : MyDerivedClassBuilder
    {
        instance.CustomStuff = value;
        return instance;
    }

    public static T SetCustomStuff<T>(this T instance, string value)
        where T : MyDerivedClassBuilder
    {
        instance.CustomStuff = new CustomClass(value);
        return instance;
    }

    public static MyDerivedClass Build(this MyDerivedClassBuilder instance)
    {
        return new MyDerivedClass(instance.EnumValue, instance.User, instance.CustomStuff);
    }
}

现在,您可以使用某种fluent API样式来构造实例:

代码语言:javascript
复制
    static void Main(string[] args)
    {
        MyBaseClass baseInstance = new MyBaseClassBuilder()
            .SetEnumValue("Alpha")
            .SetUser("Big Duke")
            .Build();

        MyDerivedClass derivedInstance = new MyDerivedClassBuilder()
            .SetEnumValue(SomeEnum.Bravo)
            .SetUser(new User("Lt. Col. Kilgore"))
            .SetCustomStuff("Smells like victory")
            .Build();
    }

最后,其他类型:

代码语言:javascript
复制
public enum SomeEnum
{
    Alpha,
    Bravo
}

public class User
{
    public User(string name)
    {
        this.Name = name;
    }

    public string Name { get; private set; }
}

public class CustomClass
{
    public CustomClass(string notation)
    {
        this.Notation = notation;
    }

    public string Notation { get; private set; }
}

通过这种方式,您可以以一种舒适的方式构造需要许多构造器参数的实例。

票数 0
EN

Stack Overflow用户

发布于 2015-11-12 12:12:27

如果您的类只有3个属性(EnumValue, ADUser, CustomClass),那么您应该只有一个构造函数,其中包括:class(EnumValue enumValue, ADUser adUser, CustomClass customClass)。应该使用支持ADUserint等的构造函数在类之外实例化CustomClassstring;例如:

代码语言:javascript
复制
class (EnumValue param, new ADUser(string_param), new CustomClass(int_param));
class (EnumValue param, new ADUser(ADUser_param), new CustomClass(string_param));

编辑您可以像我前面描述的那样将它用于内部作用域和公共部分,您可以使用和公开一个工厂(包装)类,它实际上可以接收用户和其他参数作为字符串或int,并在内部实例化和返回类。

以及您的代码片段:在程序集中创建一个类似公共类的代理,可以从外部(从其他程序集)访问该代理,并在内部.Make您的类:

代码语言:javascript
复制
   public class ClassNameBuilder
   {
        private ClassName _className;

        public ClassNameBuilder(string enumValue, string user, string custom_class) 
        { 
           _className = new ClassName(EnumToString, new User(user), new CustomClass(custom_class));

        } 

        public void CallClassNameMethod1()
        {
            return _className.Method1()
        }

        public void CallClassNameMethod2()
        {
            return _className.Method2()
        }
}

构建器类可以使用您想要构建ClassName对象的任何方法;通过这种方式,您可以公开所有类方法,而无需使用多个构造函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33670835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档