我对这个小C#quirk感到有点难过:
给定变量:
Boolean aBoolValue;
Byte aByteValue;
Run Code Online (Sandbox Code Playgroud)
以下编译:
if (aBoolValue)
aByteValue = 1;
else
aByteValue = 0;
Run Code Online (Sandbox Code Playgroud)
但这不会:
aByteValue = aBoolValue ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)
错误说:"不能隐式地将类型'int'转换为'byte'."
当然,这个怪物会编译:
aByteValue = aBoolValue ? (byte)1 : (byte)0;
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?
编辑:
使用VS2008,C#3.5
如何避免对非构造函数进行隐式转换?
我有一个函数,它接受一个整数作为参数,
但该函数也将采用字符,bools和long.
我相信它是通过隐式地施放它来实现的.
如何避免这种情况,以便函数只接受匹配类型的参数,否则将拒绝编译?
有一个关键字"显式"但它不适用于非构造函数.:\
我该怎么办?
以下程序编译,虽然我不喜欢:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
Run Code Online (Sandbox Code Playgroud)
*请务必指出任何滥用术语和假设的行为
在Java中,当你这样做
int b = 0;
b = b + 1.0;
Run Code Online (Sandbox Code Playgroud)
您可能会丢失精度错误.但是,如果你这样做,为什么呢?
int b = 0;
b += 1.0;
Run Code Online (Sandbox Code Playgroud)
没有任何错误?
我有一个Thing可以从a中隐式转换的类string.当我Thing直接使用参数调用方法时,正确完成了stringto Thing的强制转换.
但是,如果我使用反射调用相同的方法,它会抛出异常
System.ArgumentException : Object of type 'System.String' cannot be
converted to type 'Things.Program+Thing'.
Run Code Online (Sandbox Code Playgroud)
也许有充分的理由,但我无法弄明白.有人知道如何使用反射工作吗?
namespace Things
{
class Program
{
public class Thing
{
public string Some;
public static implicit operator Thing(string s)
{
return new Thing {Some = s};
}
}
public void showThing(Thing t)
{
Console.WriteLine("Some = " + t.Some);
}
public void Main()
{
showThing("foo");
MethodInfo showThingReflected = GetType().GetMethod("showThing");
showThingReflected.Invoke(this, new dynamic[] {"foo"});
}
}
} …Run Code Online (Sandbox Code Playgroud) List("a").contains(5)
Run Code Online (Sandbox Code Playgroud)
因为a Int永远不会包含在列表中String,所以这应该在编译时生成错误,但事实并非如此.
它浪费并默默地测试String列表中包含的每个内容的相等性5,这些内容永远不会成立(在Scala中"5"永远不等于5).
这被称为" '包含'问题 ".而一些人暗示,如果一个类型系统无法正确地输入这样的语义,那么为什么要经过强制执行类型的额外的努力.所以我认为这是一个需要解决的重要问题.
类型参数化B >: A的List.contains输入的任何类型的是该类型的超类型A(包含在列表中的元素的类型).
trait List[+A] {
def contains[B >: A](x: B): Boolean
}
Run Code Online (Sandbox Code Playgroud)
此类型参数化是必要的,因为+A声明列表在类型上是协变的A,因此A不能在逆变位置中使用,即作为输入参数的类型.协变列表(必须是不可变的)对于扩展比强制列表(可以是可变的)更强大.
A是String在上面的例子有问题,但Int不是的超类型String,所以发生了什么事?该隐含包容 Scala中,决定Any是两者的相互超String和Int.
Scala的创建者Martin Odersky 建议修复将限制输入类型B仅限于那些具有equals方法的类型Any.
trait List[+A] …Run Code Online (Sandbox Code Playgroud) 我刚刚看到它在最近的一个答案中使用:
public static implicit operator bool(Savepoint sp)
{
return sp != null;
}
Run Code Online (Sandbox Code Playgroud)
为什么我们在这里需要隐含的词,这是什么意思?
什么是implicit_cast?什么时候我应该更喜欢implicit_cast而不是static_cast?
是否可以让编译器自动将我的Enum值转换为字符串,这样我就可以避免每次都显式调用ToString方法.这是我想做的一个例子:
enum Rank { A, B, C }
Rank myRank = Rank.A;
string myString = Rank.A; // Error: Cannot implicitly convert type 'Rank' to 'string'
string myString2 = Rank.A.ToString(); // OK: but is extra work
Run Code Online (Sandbox Code Playgroud) 给定此类具有隐式转换运算符:
public class MyDateTime
{
public static implicit operator MyDateTime(System.Int64 encoded)
{
return new MyDateTime(encoded);
}
public MyDateTime(System.Int64 encoded)
{
_encoded = encoded;
}
System.Int64 _encoded;
}
Run Code Online (Sandbox Code Playgroud)
我现在可以做以下事情:
long a = 5;
MyDateTime b = a;
Run Code Online (Sandbox Code Playgroud)
但不是以下内容:
long f = 5;
object g = f;
MyDateTime h = g;
Run Code Online (Sandbox Code Playgroud)
这给出了编译时间:
无法将类型'object'隐式转换为'MyDateTime'.
我感觉合理.
现在我修改前面的例子如下:
long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
Run Code Online (Sandbox Code Playgroud)
编译好了.现在我得到一个运行时InvalidCastException:
无法将"System.Int64"类型的对象强制转换为"MyDateTime"类型.
这告诉我C#隐式转换运算符仅在编译时应用,并且在.NET运行时试图将对象动态转换为另一种类型时不应用.
我的问题:
顺便说一句,完整的应用程序是我Delegate.DynamicInvoke()用来调用一个带MyDateTime参数的函数,而我传递给的参数的类型很DynamicInvoke长.
c# dynamic-cast type-conversion implicit-cast dynamic-invoke
在此代码中,分配给b1有效,但它不允许分配给b2(有或没有静态强制转换).我实际上是试图解决相反的问题,公共继承但不是隐式转换为基础.然而似乎从未使用过演员.为什么是这样?
struct B {};
struct D1 : private B {
operator B&() {return *this;}
B& getB() {return *this;}
};
struct D2 : public B {
explicit operator B&() {return *this;}
};
struct D3 : public B {
operator B&() = delete;
};
void funB(B& b){}
int main () {
D1 d1;
funB(d1.getB()); // works
// funB(d1); // fails to compile with 'inaccessible base class
D2 d2;
funB(d2); // works
D3 d3;
funB(d3); // works
return 0;
}
Run Code Online (Sandbox Code Playgroud) implicit-cast ×10
c# ×5
c++ ×3
casting ×3
.net ×1
boost ×1
contains ×1
covariance ×1
dynamic-cast ×1
enums ×1
function ×1
inheritance ×1
java ×1
list ×1
reflection ×1
scala ×1
static-cast ×1
types ×1