没有赋值的隐式转换?

aro*_*eer 4 c# casting implicit

保留的问题 - 请参阅底部的编辑
我正在开发一个小型函数库,基本上是通过隐藏基本的圈复杂度来提供一些可读性.调用提供程序(调用Select<T>帮助程序工厂Select),用法类似于

public Guid? GetPropertyId(...)
{
    return Select
        .Either(TryToGetTheId(...))
        .Or(TrySomethingElseToGetTheId(...))
        .Or(IGuessWeCanTryThisTooIfWeReallyHaveTo(...))
        //etc.
        ;
}
Run Code Online (Sandbox Code Playgroud)

和库会照顾短路,等我还添加了从隐式转换Select<T>T的,所以我可以写

public Guid GetPropertyId(...)
{
    ServiceResult result = Select
        .Either(TryToGetTheId(...))
        .Or(TrySomethingElseToGetTheId(...));

    return result.Id;
}
Run Code Online (Sandbox Code Playgroud)

我真正希望能够做的是在没有赋值的情况下隐式转换为T:

public Guid GetPropertyId(...)
{
    return 
        //This is the part that I want to be implicitly cast to a ServiceResult
        Select
        .Either(TryToGetTheId(...))
        .Or(TrySomethingElseToGetTheId(...))
        //Then I want to access this property on the result of the cast
        .Id;
}
Run Code Online (Sandbox Code Playgroud)

但是,指定的语法不起作用 - 我必须将其分配给变量,或者显式地转换它.有没有办法获得内联隐式转换?

编辑

我想要做的是:

class Foo { 
    public int Fuh { get; set; } 
}

class Bar {
    private Foo _foo;
    public static implicit operator Foo (Bar bar)
    {
        return bar._foo;
    }
}

//What I have to do
Foo bar = GetABar();
DoSomethingWith(bar.Fuh);

//What I want to do
DoSomethingWith(GetABar().Fuh);
Run Code Online (Sandbox Code Playgroud)

zin*_*lon 5

虽然隐式转换在这里不起作用,但通过添加Value属性可能比显式转换更好Select<T>.然后你的表达将是Select.[operations].Value.Id,这仍然相当不错.


Eri*_*ert 5

我的问题是:当使用成员访问("点")运算符时,有没有办法告诉编译器查找Bar的成员和Bar可以隐式转换的类型?

是的,有两种方法可以做到这一点.

第一种叫做"继承".你这样做:

class Bar : Blah { ... }
...
Bar bar = new Bar();
bar.Whatever();  // member access will look up members of both Bar and Blah.
Blah blah = bar; // bar is implicitly convertible to Blah.
Run Code Online (Sandbox Code Playgroud)

这告诉编译器"当你查找Bar的成员时,也要查找Blah的成员".它还告诉编译器Bar的实例可以隐式转换为Blah类型.

Blah可以是类或接口类型.

第二个称为"类型参数的类和接口约束".你提示像这样的编译器:

void M<T>(T t) where T : Blah
{
    t.Whatever(); // member access looks up members of Blah on t
    Blah blah = t; // t is implicitly convertible to Blah
Run Code Online (Sandbox Code Playgroud)

现在t可以隐式转换为Blah,而t上的成员访问将包括在Blah上声明的成员.

同样,Blah可以是接口或类类型.

C#中没有其他方法可以影响类型Bar上的成员查找,以便在Blah类型上声明添加的成员,其中Bar可以隐式转换为Blah.