英文:
How to annotate the tuple with unknown at advance keys names and pairs number in C#?
问题
The method HasInvalidInputs
accepts the tuple with keys and values, herewith the number of pairs, and also keys names are unknown at advance.
public class ValidatableControlsGroup
{
public static bool HasInvalidInputs(object /* TODO specify more exact type */ controlsPayload)
{
// TODO implement
return true;
}
}
If it was TypeScript, in the above code it will be { [key: string]: ValidatableControl.Payload }
instead of object
. The usage of ValidatableControlsGroup.Payload
could be:
public partial class TaskManager : ComponentBase
{
private (ValidatableControl.Payload taskTitle, ValidatableControl.Payload taskDescription) controlsPayload = (
taskTitle: new ValidatableControl.Payload(initialValue: "", new TaskTitleInputtedDataValidation()),
taskDescription: new ValidatableControl.Payload(initialValue: "", new TaskTitleInputtedDataValidation())
);
private void updateTask()
{
if (ValidatableControlsGroup.HasInvalidInputs(this.controlsPayload))
{
ValidatableControlsGroup.PointOutValidationErrors(this.controlsPayload);
return;
}
this.targetTask.Title = this.controlsPayload.taskTitle.GetExpectedToBeValidValue();
this.targetTask.Description = this.controlsPayload.taskDescription.GetExpectedToBeValidValue();
// ...
}
}
Inside TaskManager
, we need to access each ValidatableControl.Payload
by key, which is why I want to use the tuple with keys. If it were TypeScript, the type of controlsPayload
would be { taskTitle: ValidatableControl.Payload; taskDescription: ValidatableControl.Payload }
, which is compatible with the generalized { [key: string]: ValidatableControl.Payload }
parameter of ValidatableControlsGroup.HasInvalidInputs
.
Please note that enumerating like if (ValidatableControlsGroup.HasInvalidInputs(item1, item2, item3, item4))
is not allowed because ValidatableControlsGroup
is being developed as a library class, thus it takes care of routines like the extraction of elements from the tuple.
Lastly, in my case, the HasInvalidInputs
method needs only values, but not keys. However, if transforming to an array is required, the HasInvalidInputs
method, as the library class, must take care of this routine.
Regarding my case, the HasInvalidInputs
method does not need the keys - only the values. However, the keys are required in TaskManager
. If the types of controlsPayload
parameter are set to ValidatableControl.Payload[]
, the library user will be forced to transform the tuple to an array, which is unacceptable for a library class because the library class must take care of such routines.
英文:
The method HasInvalidInputs
accepts the tuple with keys and values, herewith the number of pairs, and also keys names are unknown at advance.
public class ValidatableControlsGroup
{
public static bool HasInvalidInputs(object /* TODO specify more exact type */ controlsPayload)
{
// TODO implement
return true;
}
}
If it was the TypeScript, in above code it will be { [key: string]: ValidatableControl.Payload }
instead of object
. The usage of ValidatableControlsGroup.Payload
could be:
public partial class TaskManager : ComponentBase
{
private (ValidatableControl.Payload taskTitle, ValidatableControl.Payload taskDescription) controlsPayload = (
taskTitle: new ValidatableControl.Payload(initialValue: "", new TaskTitleInputtedDataValidation()),
taskDescription: new ValidatableControl.Payload(initialValue: "", new TaskTitleInputtedDataValidation())
);
private void updateTask()
{
if (ValidatableControlsGroup.HasInvalidInputs(this.controlsPayload))
{
ValidatableControlsGroup.PointOutValidationErrors(this.controlsPayload);
return;
}
this.targetTask.Title = this.controlsPayload.taskTitle.GetExpectedToBeValidValue();
this.targetTask.Description = this.controlsPayload.taskDescription.GetExpectedToBeValidValue();
// ...
}
}
Inside TaskManager
we need to access to each ValidatableControl.Payload
by key that is why I want to use the tuple with keys.
If it was the TypeScript, the type of controlsPayload
was { taskTitle: ValidatableControl.Payload; taskDescription: ValidatableControl.Payload }
which is compatible with generalized { [key: string]: ValidatableControl.Payload }
of parameter of ValidatableControlsGroup.HasInvalidInputs
.
Please note that the enumerating like if (ValidatableControlsGroup.HasInvalidInputs(item1, item2, item3, item4))
is not allowed because the ValidatableControlsGroup
is being developed as library class thus it take care about routines like extraction of the elements from the tuple.
Lastly, in my case the HasInvalidInputs
method needs only values, but not keys.
However, if the transforming to array required, the HasInvalidInputs
as the library class must take care about this routine.
Regarding my case HasInvalidInputs
method does not need the keys - it is enough the values.
However, the keys are required in TaskManager
. If will set the types of controlsPayload
parameter to ValidatableControl.Payload[]
, the library user will be forced to transform the tuple to array that is unacceptable for library class because the library class must take care about such routines.
答案1
得分: 2
以下是翻译好的部分:
你可以使用泛型:
public void Foo<TKey, TValue>((TKey Key, TValue Value) tuple)
{
Console.WriteLine(tuple.Key);
}
var f = ("foo", "bar");
Foo(f);
然而,个人观点:
ValidatableControlsGroup
正在作为库类开发,因此它负责从元组中提取元素等例行程序。
然后只需定义一个接口,并将其用于方法参数类型。不应该从库代码中公开或接受值元组。它们应该最多跨越一个边界,最好在同一个程序集内。但这是我的个人观点。
英文:
You could use generics:
public void Foo<TKey, TValue>((TKey Key, TValue Value) tuple)
{
Console.WriteLine(tuple.Key);
}
var f = ("foo", "bar");
Foo(f);
However, opinion time:
> ValidatableControlsGroup
is being developed as library class thus it take care about routines like extraction of the elements from the tuple.
Then just define an interface and use that for the method parameter type. Value tuples should not be exposed from or accepted by library code. They should be used to cross one boundary at most, preferably within the same assembly. But that's IMHO.
答案2
得分: 2
以下是要翻译的内容:
事实上,ValueTuple
家族的成员都是 struct
。因此,如果您需要表示它们的类型,object
似乎是唯一的选择。
另一种方法是添加一堆重载的方法,以涵盖可能传递的元组类型,然后将它们转换为数组。
public static bool HasInvalidInputs(ValueTuple<ValidatableControl.Payload> controlsPayload)
=> HasInvalidInputs(controlsPayload.Item1);
public static bool HasInvalidInputs(ValueTuple<ValidatableControl.Payload, ValidatableControl.Payload> controlsPayload)
=> HasInvalidInputs(controlsPayload.Item1, controlsPayload.Item2);
......
private static bool HasInvalidInputs(params object[] controlsPayload)
{
}
一言以蔽之,您的问题在于找不到适合此方法的参数类型。也许您应该重新考虑接口。
英文:
The fact is the members of the ValueTuple
family are all struct
s. So if you need a type to represent them, object
seems to be the only choice.
Another approach is adding a bunch of overloaded methods to cover the tuple types you may pass in, and then convert them to arrays.
public static bool HasInvalidInputs(ValueTuple<ValidatableControl.Payload> controlsPayload)
=> HasInvalidInputs(controlsPayload.Item1);
public static bool HasInvalidInputs(ValueTuple<ValidatableControl.Payload, ValidatableControl.Payload> controlsPayload)
=> HasInvalidInputs(controlsPayload.Item1, controlsPayload.Item2);
......
private static bool HasInvalidInputs(params object[] controlsPayload)
{
}
In a word, your issue is that you cannot find a suitable parameter type for this method. Perhaps you should reconsider the interface.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论