C# 测试泛型类型是否为字符串的最佳方法?(C#)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to test if a generic type is a string? (C#)
提问by Rex M
I have a generic class that should allow any type, primitive or otherwise. The only problem with this is using default(T)
. When you call default on a value type or a string, it initializes it to a reasonable value (such as empty string). When you call default(T)
on an object, it returns null. For various reasons we need to ensure that if it is not a primitive type, then we will have a default instance of the type, notnull. Here is attempt 1:
我有一个泛型类,它应该允许任何类型、原始类型或其他类型。唯一的问题是使用default(T)
. 当您对值类型或字符串调用 default 时,它会将其初始化为一个合理的值(例如空字符串)。当您调用default(T)
一个对象时,它返回 null。由于各种原因,我们需要确保如果它不是原始类型,那么我们将拥有该类型的默认实例,而不是null。这是尝试1:
T createDefault()
{
if(typeof(T).IsValueType)
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
Problem - string is not a value type, but it does not have a parameterless constructor. So, the current solution is:
问题 - 字符串不是值类型,但它没有无参数构造函数。所以,目前的解决方案是:
T createDefault()
{
if(typeof(T).IsValueType || typeof(T).FullName == "System.String")
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
}
But this feels like a kludge. Is there a nicer way to handle the string case?
但这感觉就像一团糟。有没有更好的方法来处理字符串情况?
采纳答案by Matt Hamilton
Keep in mind that default(string) is null, not string.Empty. You may want a special case in your code:
请记住,default(string) 为空,而不是 string.Empty。您可能需要在代码中使用特殊情况:
if (typeof(T) == typeof(String)) return (T)(object)String.Empty;
回答by FlySwat
if (typeof(T).IsValueType || typeof(T) == typeof(String))
{
return default(T);
}
else
{
return Activator.CreateInstance<T>();
}
Untested, but the first thing that came to mind.
未经测试,但想到的第一件事。
回答by jfs
You can use the TypeCodeenumeration. Call the GetTypeCode method on classes that implement the IConvertible interface to obtain the type code for an instance of that class. IConvertible is implemented by Boolean, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime, Char, and String, so you can check for primitive types using this. More info on "Generic Type Checking".
您可以使用TypeCode枚举。对实现 IConvertible 接口的类调用 GetTypeCode 方法以获取该类实例的类型代码。IConvertible 由 Boolean、SByte、Byte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Decimal、DateTime、Char 和 String 实现,因此您可以使用它检查原始类型。有关“通用类型检查”的更多信息。
回答by Anil
The discussion for String is not working here.
String 的讨论在这里不起作用。
I had to have following code for generics to make it work -
我必须有以下泛型代码才能使其工作 -
private T createDefault()
{
{
if(typeof(T).IsValueType)
{
return default(T);
}
else if (typeof(T).Name == "String")
{
return (T)Convert.ChangeType(String.Empty,typeof(T));
}
else
{
return Activator.CreateInstance<T>();
}
}
}
回答by theoski
Personally, I like method overloading:
就个人而言,我喜欢方法重载:
public static class Extensions {
public static String Blank(this String me) {
return String.Empty;
}
public static T Blank<T>(this T me) {
var tot = typeof(T);
return tot.IsValueType
? default(T)
: (T)Activator.CreateInstance(tot)
;
}
}
class Program {
static void Main(string[] args) {
Object o = null;
String s = null;
int i = 6;
Console.WriteLine(o.Blank()); //"System.Object"
Console.WriteLine(s.Blank()); //""
Console.WriteLine(i.Blank()); //"0"
Console.ReadKey();
}
}