I have a method with an out parameter that tries to do a type conversion. Basically:
我有一个带out参数的方法,它尝试进行类型转换。基本上:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
问题是,通常有人会这样称呼:
string output;
GetParameterValue(output);
This will fail because of:
由于:
destination.GetType()
destination is null, so we can't call .GetType()
on it. We also can not call:
destination为null,因此不能在其上调用. gettype()。我们也不能打电话:
typeof(destination)
because destination is a variable name not a type name.
因为destination是一个变量名,而不是类型名。
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
有什么方法可以得到被设置为null的对象的类型吗?我认为必须有一种方法来知道存储位置是什么类型,而不需要分配任何东西。
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value
is of type object.
为了提供更多的信息,我正在尝试创建一个实用方法,它将获取Oracle存储过程的输出参数。问题是DbParameter。值是对象类型。
What would be ideal would be for the developers to do something like:
对于开发人员来说,理想的做法是:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
值得注意的是,没有任何类型的铸造。实际上,你不知道“平等”的lparam,所以我就说:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
在方法中,我将知道输出变量的目标类型。我猜那是个坏假设。作为替代,我也写了这个方法:
public T GetParameterValue<T>(string paramName)
So the developers can do:
开发者可以这样做:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
我发现显式的“string”声明是重复的,特别是在实践中,如果对象属性和oracle数据类型可能发生更改,目标(请考虑ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType()
call fails. The VM has to know the type of MyObj.SomeProp
, even when its null, right? or else how would it catch cast exceptions?
但是,如果MyObj。SomeProp是空的,因此. gettype()调用失败。VM必须知道MyObj的类型。即使它是空的,对吧?或者它如何捕获抛出异常?
To partially solve my own problem, I can do:
为了部分解决我自己的问题,我可以:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp
) and in the DB. There has to be a better way...
整个想法是不需要在多个地方显式地使用类型,这样,如果数据类型发生了变化,它只需要在目标对象(myobject . someprop)和DB中更改。必须有更好的办法……
12 个解决方案
#1
31
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
有什么方法可以得到被设置为null的对象的类型吗?我认为必须有一种方法来知道存储位置是什么类型,而不需要分配任何东西。
Not necessarily. The best that you can say is that it is an object
. A null
reference does not point to any storage location, so there is no metadata from which it can make that determination.
不一定。你能说的最好的就是它是一个物体。空引用不指向任何存储位置,因此没有元数据可以从中进行判断。
The best that you could do is change it to be more generic, as in:
你能做的最好的事情就是把它变得更通用,比如:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T
can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
可以推断T的类型,因此不需要显式地为方法提供类型参数。
#2
8
It's possible if you don't mind declaring your method as a generic. Try this.
如果您不介意将您的方法声明为泛型,这是可能的。试试这个。
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
#3
7
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
以下扩展方法返回声明的参数的类型,而不考虑其内容:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
因为这是一个扩展方法,它的参数可以是一个空引用,下面所有的都可以:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType
and myNullObjType
will both be set to System.Object, not System.String.
注意myObjType和myNullObjType都将被设置为System。对象,system . string。不
If you actually want the type of obj's contents when it's not null, then change the return
line to:
如果您确实想要obj的内容类型在非空时,则将返回行改为:
return (obj != null) ? obj.GetType() : typeof( T );
#4
3
Currently you have no way of knowing what gets passed into the method. You can convert it into a generic method. Like this:
目前,您无法知道传入方法的内容。您可以将其转换为通用方法。是这样的:
public void GetParameterValue<T>(out T destination) { ... }
public void GetParameterValue
#5
2
The type of your destination variable is always System.Object
. You could just return
目标变量的类型总是System.Object。你可以返回
Convert.ChangeType(paramVal, System.Object).
#6
1
@Rally25s:
@Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
从你的信息中(答案中)不清楚那个问题是什么。如果声明为:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
正如您上面所写的那样,调用将会工作(您不需要指定类型)。我猜这对你不适用,因为你不能使用属性作为“out”参数。解决这个问题的方法是同时使用这两种方法:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
这将被称为:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
这是一种相当笨拙的方法,但并不是最糟糕的方法。
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
另一种方法(我在c++中使用过,但在c#中还没有尝试过)是让GetParameterValue()一些您自己设计的对象,然后为它实现一些隐式转换操作符。
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
#7
0
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
我认为当值为空时不可能得到类型。另外,由于您在GetParameterValue中调用,所以最好的方法(当值为null时)是获取“目标”参数的类型,即“object”。您可以考虑将类型作为参数传递给具有更多信息的GetParameterValue,例如:
public void GetParameterValue(Type sourceType, out object destination) { //... }
#8
0
If there is no instance, there is no instance type.
如果没有实例,则没有实例类型。
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
最好的方法是使用引用的类型,这意味着如果您有一个对象引用(如问题中的方法),那么引用类型就是object。
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
您可能不应该尝试将一个类型的空实例转换为另一个类型的空实例……
#9
0
In your example it would be null of type System.Object
.
在您的示例中,它是System.Object类型的null。
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
您的示例是否已编译?我得到一个“无法从'out string'转换为'out object'”错误。
#10
0
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
从理论上讲,null和C中的void指针不是一样的吗,就是说它有一个内存地址,就是这样吗?如果是这样的话,那么它就类似于在数学中没有定义结果的除法。
One could do the following for this line:
我们可以这样做:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
只要去掉第一个字符串,就不会重复了:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
不一定是你要找的,虽然有一个问题,如何解释零?
#11
0
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
#12
-1
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
或
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
这样,我们就可以使用switch来管理不同的属性类型。
#1
31
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
有什么方法可以得到被设置为null的对象的类型吗?我认为必须有一种方法来知道存储位置是什么类型,而不需要分配任何东西。
Not necessarily. The best that you can say is that it is an object
. A null
reference does not point to any storage location, so there is no metadata from which it can make that determination.
不一定。你能说的最好的就是它是一个物体。空引用不指向任何存储位置,因此没有元数据可以从中进行判断。
The best that you could do is change it to be more generic, as in:
你能做的最好的事情就是把它变得更通用,比如:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T
can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
可以推断T的类型,因此不需要显式地为方法提供类型参数。
#2
8
It's possible if you don't mind declaring your method as a generic. Try this.
如果您不介意将您的方法声明为泛型,这是可能的。试试这个。
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
#3
7
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
以下扩展方法返回声明的参数的类型,而不考虑其内容:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
因为这是一个扩展方法,它的参数可以是一个空引用,下面所有的都可以:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType
and myNullObjType
will both be set to System.Object, not System.String.
注意myObjType和myNullObjType都将被设置为System。对象,system . string。不
If you actually want the type of obj's contents when it's not null, then change the return
line to:
如果您确实想要obj的内容类型在非空时,则将返回行改为:
return (obj != null) ? obj.GetType() : typeof( T );
#4
3
Currently you have no way of knowing what gets passed into the method. You can convert it into a generic method. Like this:
目前,您无法知道传入方法的内容。您可以将其转换为通用方法。是这样的:
public void GetParameterValue<T>(out T destination) { ... }
public void GetParameterValue
#5
2
The type of your destination variable is always System.Object
. You could just return
目标变量的类型总是System.Object。你可以返回
Convert.ChangeType(paramVal, System.Object).
#6
1
@Rally25s:
@Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
从你的信息中(答案中)不清楚那个问题是什么。如果声明为:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
正如您上面所写的那样,调用将会工作(您不需要指定类型)。我猜这对你不适用,因为你不能使用属性作为“out”参数。解决这个问题的方法是同时使用这两种方法:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
这将被称为:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
这是一种相当笨拙的方法,但并不是最糟糕的方法。
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
另一种方法(我在c++中使用过,但在c#中还没有尝试过)是让GetParameterValue()一些您自己设计的对象,然后为它实现一些隐式转换操作符。
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
#7
0
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
我认为当值为空时不可能得到类型。另外,由于您在GetParameterValue中调用,所以最好的方法(当值为null时)是获取“目标”参数的类型,即“object”。您可以考虑将类型作为参数传递给具有更多信息的GetParameterValue,例如:
public void GetParameterValue(Type sourceType, out object destination) { //... }
#8
0
If there is no instance, there is no instance type.
如果没有实例,则没有实例类型。
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
最好的方法是使用引用的类型,这意味着如果您有一个对象引用(如问题中的方法),那么引用类型就是object。
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
您可能不应该尝试将一个类型的空实例转换为另一个类型的空实例……
#9
0
In your example it would be null of type System.Object
.
在您的示例中,它是System.Object类型的null。
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
您的示例是否已编译?我得到一个“无法从'out string'转换为'out object'”错误。
#10
0
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
从理论上讲,null和C中的void指针不是一样的吗,就是说它有一个内存地址,就是这样吗?如果是这样的话,那么它就类似于在数学中没有定义结果的除法。
One could do the following for this line:
我们可以这样做:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
只要去掉第一个字符串,就不会重复了:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
不一定是你要找的,虽然有一个问题,如何解释零?
#11
0
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
#12
-1
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
或
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
这样,我们就可以使用switch来管理不同的属性类型。