使用多个可初始化字段简化 class 的构造函数
Simplify Constructor for class with multiple initialisable fields
我目前遇到以下问题:
我有一个 class 其中包括 3 个不同的字段
- 枚举 x
- ActiveDirectory 用户是
- 自定义类 z
可以通过传递字符串或枚举对象来初始化枚举。
ADUser 可以通过传递字符串 (LoginName) 或用户本身来初始化,CustomClass 可以通过传递字符串、int 或对象来初始化。
现在我想初始化 class 以传递所有不同的组合,例如
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# 对象并对其进行转换并用它做一些事情,但我认为这只是一个肮脏的解决方法?
编辑
class 包含在一个库中,因此可以在内部使用,但也可以 public。对于内部用途,传递对象的具体版本没有问题。
但是如果我在其他解决方案中使用它 public 这些解决方案只能引用字符串或 int 值。因此 class 应该能够 'take' 值并在初始化时转换它们,因为它可以访问所有真实对象。
也许这能稍微说明问题。
这里是一些改名的代码片段:
#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
如果您的 class 只有 3 个属性 (EnumValue, ADUser, CustomClass
),那么您应该只有一个具有这些属性的构造函数:class(EnumValue enumValue, ADUser adUser, CustomClass customClass)
。 ADUser
和 CustomClass
应该使用支持 string
或 int
等的构造函数在 class 之外实例化;
示例:
class (EnumValue param, new ADUser(string_param), new CustomClass(int_param));
class (EnumValue param, new ADUser(ADUser_param), new CustomClass(string_param));
编辑
您可以像我上面描述的那样使用它用于内部范围,对于 public 部分,您可以使用和公开一个工厂(包装器)class,它实际上可以接收用户和其他参数作为字符串或 int 并在内部实例化return 你的 class。
除了您的代码段: 在您的程序集中创建一个类似 public class 的代理,它可以从外部(从其他程序集)访问。使您的 class 内部:
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()
}
}
构建器class可以使用您想要构建ClassName对象的任何方法;这样您就可以在不使用多个构造函数的情况下公开所有 class 方法。
我认为最好的办法是使用构建器模式。您甚至可以将它与派生的 classes.
一起使用
我要构建的 class:
public class MyBaseClass
{
public MyBaseClass(SomeEnum enumValue, User user)
{
}
}
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass(SomeEnum enumValue, User user, CustomClass customStuff)
: base(enumValue, user)
{
}
}
现在让我们添加一个构建器 class,它具有额外的扩展 class 以使事情变得更加舒适(它是一种使用 C# 扩展方法 wizadry 的扩展构建器模式):
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);
}
}
现在让我们为派生的 class:
做同样的事情
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);
}
}
现在您可以以某种流畅的 API 风格方式构建您的实例:
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();
}
最后是附加类型:
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; }
}
通过这种方式,您可以轻松地构造需要许多构造函数参数的实例。
我目前遇到以下问题:
我有一个 class 其中包括 3 个不同的字段
- 枚举 x
- ActiveDirectory 用户是
- 自定义类 z
可以通过传递字符串或枚举对象来初始化枚举。 ADUser 可以通过传递字符串 (LoginName) 或用户本身来初始化,CustomClass 可以通过传递字符串、int 或对象来初始化。
现在我想初始化 class 以传递所有不同的组合,例如
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# 对象并对其进行转换并用它做一些事情,但我认为这只是一个肮脏的解决方法?
编辑
class 包含在一个库中,因此可以在内部使用,但也可以 public。对于内部用途,传递对象的具体版本没有问题。
但是如果我在其他解决方案中使用它 public 这些解决方案只能引用字符串或 int 值。因此 class 应该能够 'take' 值并在初始化时转换它们,因为它可以访问所有真实对象。
也许这能稍微说明问题。
这里是一些改名的代码片段:
#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
如果您的 class 只有 3 个属性 (EnumValue, ADUser, CustomClass
),那么您应该只有一个具有这些属性的构造函数:class(EnumValue enumValue, ADUser adUser, CustomClass customClass)
。 ADUser
和 CustomClass
应该使用支持 string
或 int
等的构造函数在 class 之外实例化;
示例:
class (EnumValue param, new ADUser(string_param), new CustomClass(int_param));
class (EnumValue param, new ADUser(ADUser_param), new CustomClass(string_param));
编辑 您可以像我上面描述的那样使用它用于内部范围,对于 public 部分,您可以使用和公开一个工厂(包装器)class,它实际上可以接收用户和其他参数作为字符串或 int 并在内部实例化return 你的 class。
除了您的代码段: 在您的程序集中创建一个类似 public class 的代理,它可以从外部(从其他程序集)访问。使您的 class 内部:
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()
}
}
构建器class可以使用您想要构建ClassName对象的任何方法;这样您就可以在不使用多个构造函数的情况下公开所有 class 方法。
我认为最好的办法是使用构建器模式。您甚至可以将它与派生的 classes.
一起使用我要构建的 class:
public class MyBaseClass
{
public MyBaseClass(SomeEnum enumValue, User user)
{
}
}
public class MyDerivedClass : MyBaseClass
{
public MyDerivedClass(SomeEnum enumValue, User user, CustomClass customStuff)
: base(enumValue, user)
{
}
}
现在让我们添加一个构建器 class,它具有额外的扩展 class 以使事情变得更加舒适(它是一种使用 C# 扩展方法 wizadry 的扩展构建器模式):
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);
}
}
现在让我们为派生的 class:
做同样的事情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);
}
}
现在您可以以某种流畅的 API 风格方式构建您的实例:
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();
}
最后是附加类型:
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; }
}
通过这种方式,您可以轻松地构造需要许多构造函数参数的实例。