在编程接口时,我发现我正在进行大量的转换或对象类型转换.
这两种转换方法有区别吗?如果是,是否有成本差异或这对我的计划有何影响?
public interface IMyInterface
{
void AMethod();
}
public class MyClass : IMyInterface
{
public void AMethod()
{
//Do work
}
// Other helper methods....
}
public class Implementation
{
IMyInterface _MyObj;
MyClass _myCls1;
MyClass _myCls2;
public Implementation()
{
_MyObj = new MyClass();
// What is the difference here:
_myCls1 = (MyClass)_MyObj;
_myCls2 = (_MyObj as MyClass);
}
}
Run Code Online (Sandbox Code Playgroud)
另外,什么是"一般"首选方法?
我注意到Resharper建议我转过身:
if (myObj.myProp is MyType)
{
...
}
Run Code Online (Sandbox Code Playgroud)
进入这个:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Run Code Online (Sandbox Code Playgroud)
为什么会建议这种变化?我已经习惯了Resharper建议优化更改和代码减少更改,但这感觉就像它想要我的单一陈述并将其转换为双线程.
根据MSDN:
一个是 表达式如果两个满足以下条件的值为true:
表达式不为空.表达式可以转换为类型.也就是说,表单的强制转换表达式将在
(type)(expression)不抛出异常的情况下完成.
我是否误读了,或者没有is完全相同的检查,只需要在一行中而不需要为空检查显式创建另一个局部变量?
我bool从(非泛型,异构)集合中提取值.
该as运营商只能与引用类型使用,所以这是不可能做到的使用as尝试安全播到bool:
// This does not work: "The as operator must be used with a reference type ('bool' is a value type)"
object rawValue = map.GetValue(key);
bool value = rawValue as bool;
Run Code Online (Sandbox Code Playgroud)
有没有类似的东西可以做到安全地将对象转换为值类型而没有InvalidCastExceptionif的可能性,无论出于何种原因,该值不是布尔值?
如果我有
public class AImplementation:IAInterface
{
void IAInterface.AInterfaceMethod()
{
}
void AnotherMethod()
{
((IAInterface)this).AInterfaceMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
如何AInterfaceMethod()从AnotherMethod()没有明确的投射来打电话?
编辑:底部的评论.还有,这个.
这就是让我感到困惑的一点.我的理解是,如果我有这样的枚举......
enum Animal
{
Dog,
Cat
}
Run Code Online (Sandbox Code Playgroud)
...我基本上完成的是定义了一个用两个定义的值调用的值类型Animal,Dog和Cat.这种类型派生自引用类型 System.Enum(值类型通常不能执行的操作 - 至少不在C#中 - 但在这种情况下是允许的),并且具有用于在int值之间来回转换的工具.
如果我刚刚描述上面的枚举类型的方式是真的,那么我希望以下代码抛出InvalidCastException:
public class Program
{
public static void Main(string[] args)
{
// Box it.
object animal = Animal.Dog;
// Unbox it. How are these both successful?
int i = (int)animal;
Enum e = (Enum)animal;
// Prints "0".
Console.WriteLine(i);
// Prints "Dog".
Console.WriteLine(e);
}
}
Run Code Online (Sandbox Code Playgroud)
通常,您不能将值类型System.Object从其确切类型以外的任何其他方式取消装箱.那以上怎么可能呢?这是因为如果该 …
为什么这个显式转换会抛出Specified cast is not valid.异常?
decimal d = 10m;
object o = d;
int x = (int)o;
Run Code Online (Sandbox Code Playgroud)
但这有效:
int x = (int)(decimal)o;
Run Code Online (Sandbox Code Playgroud) 我今天早些时候发生的事情让我摸不着头脑.
Nullable<T>可以为任何类型的变量赋值null.例如:
int? i = null;
Run Code Online (Sandbox Code Playgroud)
起初,我看不出如何做到这一点是可能的,而不以某种方式从定义的隐式转换object到Nullable<T>:
public static implicit operator Nullable<T>(object box);
Run Code Online (Sandbox Code Playgroud)
但是上面的运算符显然不存在,就好像它确实如此,那么下面的内容也必须是合法的,至少在编译时(它不是):
int? i = new object();
Run Code Online (Sandbox Code Playgroud)
然后我意识到,也许Nullable<T>类型可以定义一个隐式转换为一些永远无法实例化的任意引用类型,如下所示:
public abstract class DummyBox
{
private DummyBox()
{ }
}
public struct Nullable<T> where T : struct
{
public static implicit operator Nullable<T>(DummyBox box)
{
if (box == null)
{
return new Nullable<T>();
}
// This should never be possible, as a DummyBox cannot be instantiated.
throw new InvalidCastException();
}
} …Run Code Online (Sandbox Code Playgroud) 为了说明我的问题,请考虑这些简单的例子(C#):
object reference = new StringBuilder();
object box = 42;
object unset = null;
// CASE ONE: bad reference conversions (CIL instrcution 0x74 'castclass')
try
{
string s = (string)reference;
}
catch (InvalidCastException ice)
{
Console.WriteLine(ice.Message); // Unable to cast object of type 'System.Text.StringBuilder' to type 'System.String'.
}
try
{
string s = (string)box;
}
catch (InvalidCastException ice)
{
Console.WriteLine(ice.Message); // Unable to cast object of type 'System.Int32' to type 'System.String'.
}
// CASE TWO: bad unboxing conversions (CIL instrcution …Run Code Online (Sandbox Code Playgroud) 根据as运营商的文档,as"用于在兼容的参考类型之间执行某些类型的转换".由于Nullable 实际上是一个值类型,我希望as不会使用它.但是,此代码编译并运行:
object o = 7;
int i = o as int? ?? -1;
Console.WriteLine(i); // output: 7
Run Code Online (Sandbox Code Playgroud)
这是正确的行为吗?文件是as错的吗?我错过了什么吗?
以下两个C#函数的区别仅在于将参数的左/右顺序交换为equals运算符==.(的类型IsInitialized是bool).使用C#7.1和.NET 4.7.
static void A(ISupportInitialize x)
{
if ((x as ISupportInitializeNotification)?.IsInitialized == true)
throw null;
}
Run Code Online (Sandbox Code Playgroud)
static void B(ISupportInitialize x)
{
if (true == (x as ISupportInitializeNotification)?.IsInitialized)
throw null;
}
Run Code Online (Sandbox Code Playgroud)
但是第二个的IL代码似乎要复杂得多.例如,B是:
newobj和initobj;[0] bool flag
nop
ldarg.0
isinst [System]ISupportInitializeNotification
dup
brtrue.s L_000e
pop
ldc.i4.0
br.s L_0013
L_000e: callvirt instance bool [System]ISupportInitializeNotification::get_IsInitialized()
L_0013: stloc.0
ldloc.0
brfalse.s …Run Code Online (Sandbox Code Playgroud)