相关疑难解决方法(0)

隐式强制转换对委托类型推断的意外影响

我有一个Money带有隐式转换的简单类型decimal:

struct Money
{
    decimal innerValue;
    public static implicit operator Money(decimal value)
    {
        return new Money { innerValue = value };
    }
    public static explicit operator decimal(Money value)
    {
        return value.innerValue;
    }

    public static Money Parse(string s)
    {
        return decimal.Parse(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

我定义了一个Sum()重载来操作这些值:

static class MoneyExtensions
{
    public static Money Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, Money> selector)
    {
        return source.Select(x => (decimal)selector(x)).Sum();
    }
}
Run Code Online (Sandbox Code Playgroud)

我没想到的是这种扩展方法会干扰现有的Sum()扩展方法:

var source = new[] { "2" };
Money …
Run Code Online (Sandbox Code Playgroud)

c# delegates type-inference

9
推荐指数
1
解决办法
609
查看次数

为什么具有隐式转换运算符的自定义结构上的Assert.AreEqual失败?

我创建了一个自定义结构来表示金额.它基本上是一个包装器decimal.它有一个隐式转换运算符将其强制转换为decimal.

在我的单元测试中,我断言Amount等于原始十进制值,但测试失败.

[TestMethod]
public void AmountAndDecimal_AreEqual()
{
    Amount amount = 1.5M;

    Assert.AreEqual(1.5M, amount);
}
Run Code Online (Sandbox Code Playgroud)

当我使用int(我没有创建转换运算符)时,测试确实成功.

[TestMethod]
public void AmountAndInt_AreEqual()
{
    Amount amount = 1;

    Assert.AreEqual(1, amount);
}
Run Code Online (Sandbox Code Playgroud)

当我悬停时AreEqual,它显示第一个解析为

public static void AreEqual(object expected, object actual);
Run Code Online (Sandbox Code Playgroud)

而第二个导致

public static void AreEqual<T>(T expected, T actual);
Run Code Online (Sandbox Code Playgroud)

看起来这个int1是隐式地转换为a Amount,而decimal1.5M则不是.

我不明白为什么会这样.我本来希望恰恰相反.第一次单元测试应该能够投射decimalAmount.

当我添加隐式强制转换int(没有意义)时,第二个单元测试也会失败.因此,添加隐式强制转换运算符会破坏单元测试.

我有两个问题:

  1. 这种行为有什么解释?
  2. 如何修复Amount结构,以便两个测试都能成功?

(我知道我可以改变测试来做一个明确的转换,但如果我不是绝对必须,我不会)

我的Amount结构(只是一个显示问题的最小实现)

public struct Amount …
Run Code Online (Sandbox Code Playgroud)

c# struct unit-testing implicit-conversion

7
推荐指数
1
解决办法
502
查看次数

为什么类型推断和隐式运算符在以下情况下不起作用?

我将试着用一个例子来解释我的问题:

class V<T>
{
    public readonly Func<T> Get;
    public readonly bool IsConstant;

    V(Func<T> get, bool isConstant)
    {
        Get = get;
        IsConstant = isConstant;
    }

    public static implicit operator V<T>(T value)
    {
        return new V<T>(() => value, true);
    }

    public static implicit operator V<T>(Func<T> getter)
    {
        return new V<T>(getter, false);
    }
}

void DoSomething<T>(V<T> v)
{
    //...
}

void Main()
{
    DoSomething<string>("test"); // (1) type inference is not working
    DoSomething<string>((V<string>)(() => "test")); // (2) implicit operator does not work
}
Run Code Online (Sandbox Code Playgroud)

在方法中 …

.net c# generics type-inference implicit-conversion

2
推荐指数
1
解决办法
1153
查看次数