代码之家  ›  专栏  ›  技术社区  ›  Matt Mills

无赋值隐式转换?

  •  4
  • Matt Mills  · 技术社区  · 14 年前


    我正在开发一个小型函数库,基本上是通过隐藏基本的圈复杂度来提供一些可读性。调用提供程序 Select<T> (与一家名为 Select ),用法与

    public Guid? GetPropertyId(...)
    {
        return Select
            .Either(TryToGetTheId(...))
            .Or(TrySomethingElseToGetTheId(...))
            .Or(IGuessWeCanTryThisTooIfWeReallyHaveTo(...))
            //etc.
            ;
    }
    

    选择<T> T

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

    我真正想做的是不赋值地隐式转换为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;
    }
    

    但是,指定的语法不起作用-我必须将它赋给一个变量,或者显式地强制转换它。有没有一种方法可以内联得到隐式强制转换?

    我想做的是:

    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);
    
    7 回复  |  直到 14 年前
        1
  •  5
  •   zinglon    14 年前

    Value 属性到 Select<T> Select.[operations].Value.Id

        2
  •  5
  •   Eric Lippert    14 年前

    我的问题是:当使用memberaccess(“dot”)操作符时,有没有方法告诉编译器同时查找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.
    

    这会告诉编译器“当您查找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
    

    现在t隐式地可转换为Blah,并且t上的成员访问将包括在Blah上声明的成员。

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

        3
  •  2
  •   CodingGorilla    14 年前

        4
  •  1
  •   Leo    14 年前

    如果你想把转换到guid内联,你可以做一个扩展方法

    public static Guid ToGuid(this string id)
    {
        return new Guid(id);
    }
    
    public Guid GetPropertyId(...)
    {
        return Select
            .Either(TryToGetTheId(...))
            .Or(TrySomethingElseToGetTheId(...))
            .Id
            .ToGuid();
    }
    

    我不认为它真的增加了什么,但在我看来,阅读更好。

        5
  •  1
  •   Gabe Timothy Khouri    14 年前

    Or 返回一个 Select ,不是 ServiceResult ,因此编译器不可能知道您希望获得 Id 来自 服务结果 Select.Id 属性,并开始查找可能的隐式转换,以查看其中是否有一个名为 ?

    以下是您的一些选择:

    public Guid GetPropertyId(...) 
    { 
        return  ((ServiceResult)
            Select 
            .Either(TryToGetTheId(...)) 
            .Or(TrySomethingElseToGetTheId(...)))
            .Id; 
    } 
    

    class Select
    {
        public ServiceResult AsServiceResult()
        {
            return (ServiceResult)this;
        }
    }
    
    public Guid GetPropertyId(...) 
    { 
        return  
            Select 
            .Either(TryToGetTheId(...)) 
            .Or(TrySomethingElseToGetTheId(...)) 
            .AsServiceResult()
            .Id; 
    } 
    

    class Select
    {
        public Guid Id { get { return ((ServiceResult)this).Id; } }
    }
    
    public Guid GetPropertyId(...) 
    { 
        return  
            Select 
            .Either(TryToGetTheId(...)) 
            .Or(TrySomethingElseToGetTheId(...)) 
            .Id; 
    }
    
        6
  •  0
  •   abhishek    14 年前

    你试过了吗

    public Guid GetPropertyId(...)
    {
        return new Guid(Select
            .Either(TryToGetTheId(...))
            .Or(TrySomethingElseToGetTheId(...))
            .Id);
    }
    
        7
  •  0
  •   supercat    14 年前