英文:
Default parameter is still empty string
问题
我有一个继承自接口的类,定义如下:
public interface IModel
{
List<KeyValuePair<string, string>> AddValuePairs(string prefix = "");
}
一切都很好,但是当我调用这个方法并传递一个前缀时,它仍然将其视为空字符串。
public sealed class AuthURLInputModel : IModel
{
public string Username {get;set;}
public string Idnumber {get;set;}
public List<KeyValuePair<string,string>> AddValuePairs(string prefix="user")
{
var pre = !string.IsNullOrEmpty(prefix) ? prefix : string.Empty;
var keyValuePairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(ModelHelper.GetPrefixedName("username", prefix), Username),
new KeyValuePair<string, string>(ModelHelper.GetPrefixedName("idnumber", prefix), Idnumber)
};
return keyValuePairs;
}
}
调用
AddValuePairs(string prefix = "user[0]")
仍然将前缀视为空字符串,而不是传入的
"user[0]"
有什么建议吗?
英文:
I have a class that inherits from Interface with this definition
public interface IModel
{
List<KeyValuePair<string, string>> AddValuePairs(string prefix = "");
}
All is fine but when I call the method and pass a prefix it still sees it as empty.
public sealed class AuthURLInputModel : IModel
{
public string Username {get;set;}
public string Idnumber {get;set;}
public List<KeyValuePair<string,string>> AddValuePairs(string prefix="user")
{
var pre = !string.IsNullOrEmpty(prefix) ? prefix : string.Empty;
var keyValuePairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(ModelHelper.GetPrefixedName("username", prefix), Username),
new KeyValuePair<string, string>(ModelHelper.GetPrefixedName("idnumber", prefix), Idnumber)
};
return keyValuePairs;
}
}
Calls to
> AddValuePairs(string prefix = "user[0]")
still sees prefix as empty string instead of
> "user[0]"
that was passed in.
protected TModel Post<TModel, TInputModel>(string funcName, TInputModel inputModel)
where TInputModel : IModel
{
var inputs = inputModel.AddValuePairs();
}
Where TInputModel
is AuthURLInputModel
Any suggestion?
答案1
得分: 3
可选参数的默认值是在编译时根据方法调用目标表达式的编译时类型使用的。在这种情况下,编译时类型是TInputModel
,但编译器只“知道”接口中的声明,所以它确定要使用哪个默认值。
这里有一个更简单的完整示例:
using System;
public interface IFoo
{
void M(int x = 0);
}
public class Foo : IFoo
{
public void M(int x = 10)
{
Console.WriteLine(x);
}
}
class Test
{
static void Main()
{
Foo foo1 = new Foo();
IFoo foo2 = foo1;
// 输出10,因为编译器知道Foo.M的声明
foo1.M();
// 输出0,因为编译器只知道IFoo.M的声明
foo2.M();
}
}
我强烈建议您不要更改接口实现(或基类重写)方法中的默认值。这会导致混淆-正如您的问题所示。
英文:
The default value for optional parameters is used at compile-time, based on the compile-time type of the expression of the target of the method call. In this case, the compile-time type is TInputModel
, but the compiler only "knows" about the declaration in the interface, so that's how it determines which value to use by default.
Here's a simpler, complete example:
using System;
public interface IFoo
{
void M(int x = 0);
}
public class Foo : IFoo
{
public void M(int x = 10)
{
Console.WriteLine(x);
}
}
class Test
{
static void Main()
{
Foo foo1 = new Foo();
IFoo foo2 = foo1;
// Prints 10, because the compiler knows
// about the declaration of Foo.M
foo1.M();
// Prints 0, because the compiler only
// knows about the declaration of IFoo.M
foo2.M();
}
}
I would strongly advise you not to change the default value in interface-implementing (or base-class-overriding) methods. It causes confusion - as your question demonstrates.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论