有没有办法强制/限制的类型,是通过以原语? (bool,int,string,等等)。

现在,我知道你可以限制一般类型参数,以一种类型或接口实施通过 哪里 条款。然而,这并不适合该法案的基本体(据我所知),因为他们并不都有一个共同点(除了 对象 之前有人说的!:P)。

因此,我现在的想法是到刚砂砾我的牙齿和做一个大的 开关 发言,并扔一个 ArgumentException 在失败的..


编辑1:

只是澄清:

代码的定义应该是这样的:

public class MyClass<GenericType> ....

和实例:

MyClass<bool> = new MyClass<bool>(); // Legal
MyClass<string> = new MyClass<string>(); // Legal
MyClass<DataSet> = new MyClass<DataSet>(); // Illegal
MyClass<RobsFunkyHat> = new MyClass<RobsFunkyHat>(); // Illegal (but looks awesome!)

编辑2

@Jon Limjap-好点的东西我已经考虑..我肯定有一个通用方法,可用以确定该型是一个值或基准。

这可能是有用的,在立即消除了很多对象,我不想处理(但是然后你需要担心的结构的使用,如 尺寸 )..有趣的问题没有?:)

这里是:

where T : struct

采取从 MSDN.


我很好奇..能这样做。净3.x使用扩展的方法吗?创建一个接口,并实现接口在扩展的方法(其中可能会比一点脂肪开关)。再加上如果你再需要后来延伸到任何轻的定义类型,它们也可以实施相同的接口,没有变化所需的基码。

你们怎么想的?

不幸的消息是我的工作在框架2!!D


编辑3

这是如此的简单下 Jon Limjaps指针..这么简单的我几乎想要哭了,但这是伟大的,因为代码就像一个魅力!

因此,这里是什么我(你会笑!):

代码添加到一般类

bool TypeValid()
{
    // Get the TypeCode from the Primitive Type
    TypeCode code = Type.GetTypeCode(typeof(PrimitiveDataType));

    // All of the TypeCode Enumeration refer Primitive Types
    // with the exception of Object and Empty (Null).
    // Since I am willing to allow Null Types (at this time)
    // all we need to check for is Object!
    switch (code)
    {
        case TypeCode.Object:
            return false;
        default:
            return true;
    }
}

然后一个小小的实用方法,以检查的类型和投掷的一个例外,

private void EnforcePrimitiveType()
{
    if (!TypeValid())
        throw new InvalidOperationException(
            "Unable to Instantiate SimpleMetadata based on the Generic Type of '" + typeof(PrimitiveDataType).Name + 
            "' - this Class is Designed to Work with Primitive Data Types Only.");
}

所有那么需要做的是叫 EnforcePrimitiveType() 在类的构造.完成工作!:-)

只有一个缺点,这只会引发一个例外在运行时(显然),而不是设计时间。但是这没什么大不了的,可能与公用事业等 FxCop (我们不在工作中使用).

特别感谢Jon Limjap在这一个!

有帮助吗?

解决方案

原语似乎是指定的 TypeCode 枚举:

也许有方法找出如果一个对象包含的 TypeCode enum 没有必要将其转换为一个具体的目的或打电话 GetType()typeof()?

更新 它就在我的鼻子。代码样本有显示了这一点:

static void WriteObjectInfo(object testObject)
{
    TypeCode    typeCode = Type.GetTypeCode( testObject.GetType() );

    switch( typeCode )
    {
        case TypeCode.Boolean:
            Console.WriteLine("Boolean: {0}", testObject);
            break;

        case TypeCode.Double:
            Console.WriteLine("Double: {0}", testObject);
            break;

        default:
            Console.WriteLine("{0}: {1}", typeCode.ToString(), testObject);
            break;
        }
    }
}

它仍然是一个丑陋的开关。但这是一个良好的开始!

其他提示

public class Class1<GenericType> where GenericType : struct
{
}

这一似乎要做的工作。。

几乎什么@拉斯已经说:

//Force T to be a value (primitive) type.
public class Class1<T> where T: struct

//Force T to be a reference type.
public class Class1<T> where T: class

//Force T to be a parameterless constructor.
public class Class1<T> where T: new()

所有工作。净2、3和3.5.

如果你可以容忍使用工厂的方法(而不是建MyClass你叫)你总是可以做这样的事情:

class MyClass<T>
{
  private readonly T _value;

  private MyClass(T value) { _value = value; }

  public static MyClass<int> FromInt32(int value) { return new MyClass<int>(value); }
  public static MyClass<string> FromString(string value) { return new MyClass<string>(value); }
  // etc for all the primitive types, or whatever other fixed set of types you are concerned about
}

一个问题是,你会需要的类型 MyClass<AnyTypeItDoesntMatter>.FromInt32, ,这是令人讨厌。没有一个非常好的方法解决这个如果你想要维护私人性的构造,但这里有一对夫妇的解决办法:

  • 创建一个抽象的类 MyClass.让 MyClass<T> 继承 MyClass 和鸟巢内 MyClass.移动静态的方法 MyClass.这将所有的可见性工作,在成本具有访问 MyClass<T> 作为 MyClass.MyClass<T>.
  • 使用 MyClass<T> 作为给出。做一个静态的类 MyClass 它呼吁静态的方法 MyClass<T> 使用 MyClass<AnyTypeItDoesntMatter> (可能使用适当类型的每一次,仅用于笑声).
  • (更容易,但是肯定怪怪的)使一个抽象的类型 MyClass 其继承 MyClass<AnyTypeItDoesntMatter>.(针对具体性,让我们说 MyClass<int>.) 因为你可以打电话静态定义的方法基类中通过的名称源类,你现在可以使用 MyClass.FromString.

这给你的静态检查费用的更多写。

如果你是幸福的动态检查,我会用一些变在代码解决方案上。

@抢劫, Enum's将滑过 TypeValid 功能,因为它的 TypeCodeInteger.我已经更新的功能还检查 Enum.

Private Function TypeValid() As Boolean
    Dim g As Type = GetType(T)
    Dim code As TypeCode = Type.GetTypeCode(g)

    ' All of the TypeCode Enumeration refer Primitive Types
    ' with the exception of Object and Empty (Nothing).
    ' Note: must also catch Enum as its type is Integer.
    Select Case code
        Case TypeCode.Object
            Return False
        Case Else
            ' Enum's TypeCode is Integer, so check BaseType
            If g.BaseType Is GetType(System.Enum) Then
                Return False
            Else
                Return True
            End If
    End Select
End Function

你可以简化 EnforcePrimitiveType 方法的使用 typeof(PrimitiveDataType).IsPrimitive 财产。我失去了一些东西?

使用定制的 FxCop 规则不希望的标志的使用情况 MyClass<>.

具有类似的挑战,我不知道你们怎么觉得有关 请参口.它允许请求者的需要,并可以延长用自己的实现。

例如:

    public class MyClass<TKey>
    where TKey : IConvertible
{
    // class intentionally abbreviated
}

我想到的是这样一个解决方案,虽然许多建议是我的选择。

我担心的是-但是-这是误导性的潜在开发人员使用你的课吗?

干杯-谢谢

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top